0

私はExcel(2010年または2013年である可能性があり、これが後で問題になる可能性があるかどうかはわかりません)4列の文書を持っています。最初の 3 つの列には、基本的に 10 文字以上の文字列である電話番号が格納されます。4 列のみで、永遠に 1、2、3、または 4 が格納され、それがカテゴリです。列A の各数値が列BCに表示されるかどうかを確認する必要があるため、各列のすべての Excel セルを読み取り、リストに格納すると考えられます (以下で説明する問題のため、まだ実装されていません)。 . そのために、次のコードを作成します。

private void btnCargarExcel_Click(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {

                if (System.IO.File.Exists(openFileDialog1.FileName))
                {
                    filePath.Text = openFileDialog1.FileName.ToString();

                    Excel.Application xlApp;
                    Excel.Workbook xlWorkBook;
                    Excel.Worksheet xlWorkSheet;
                    Excel.Range range;

                    string str;

                    int rCnt = 0;

                    xlApp = new Microsoft.Office.Interop.Excel.Application();
                    xlWorkBook = xlApp.Workbooks.Open(openFileDialog1.FileName, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
                    xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

                    range = xlWorkSheet.UsedRange;

                    for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
                    {
                        str = (range.Cells[rCnt, 1] as Excel.Range).Value2.ToString();
                        //bd.Add(cleanString(str));

                        bd.Add(cleanString(str, 10));
                    }

                    for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
                    {
                        str = (range.Cells[rCnt, 2] as Excel.Range).Value2.ToString();
                        //bd.Add(cleanString(str));

                        bl.Add(cleanString(str, 10));
                    }

                    for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
                    {
                        str = (range.Cells[rCnt, 3] as Excel.Range).Value2.ToString();
                        //bd.Add(cleanString(str));

                        cm.Add(cleanString(str, 10));
                    }

                    nrosProcesados.Text = bd.Count().ToString();
                    listBox1.DataSource = bd;

                    noProcesadosBL.Text = bl.Count().ToString();
                    listBox2.DataSource = bl;

                    noProcesadosCM.Text = cm.Count().ToString();
                    listBox3.DataSource = cm;

                    xlWorkBook.Close(true, null, null);
                    xlApp.Quit();

                    releaseObject(xlWorkSheet);
                    releaseObject(xlWorkBook);
                    releaseObject(xlApp);
                }
                else
                {
                    MessageBox.Show("No se pudo abrir el fichero!");
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel);
                    appExcel = null;
                    System.Windows.Forms.Application.Exit();
                }
            }
        }

そのため、コードでわかるように、列のセルを反復処理し、文字列を変更した後、すべての数値をリストに格納します。ここでの問題は、列 A には 797340 セル、列 B には 91617 セル、列 C には 95891 セルがあるため、アプリケーションを実行すると、Excel をロードして PC がハングアウトするのを待ちます (12GB の RAM と Core i3 プロセッサを搭載していても)タスク マネージャーを開いてタスクを終了する必要があります。私が欲しいものを手に入れ(繰り返されない数字だけを残す)、私のPCをたむろしないための最良の解決策は何ですか?サイクルごとに別々のスレッドに分割しても問題ありませんか(私はC#で始めているので、これについてはあまり知りません。助けていただければ幸いです)。このトピックについてどう思いますか?

編集:新しいクリーンなメソッドを追加します

したがって、ここでいくつかのメンバーから読んで読んで助けを得た後、コードを少し改善しましたが、別の問題が発生しました(コードの下にコメントされています)。今すぐコードを参照してください。

// this goes first when I declare vars
public static System.Array objRowAValues;

// this goes in action when I click the button (I leave only relevant part)
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range, rngARowLast;

string str;
int rCnt = 0;

long lastACell, fullRow;

xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(openFileDialog1.FileName, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet) xlWorkBook.Worksheets.get_Item(1);

range = xlWorkSheet.UsedRange;

fullRow = xlWorkSheet.Rows.Count;
lastACell = xlWorkSheet.Cells[fullRow, 1].End(Excel.XlDirection.xlUp).Row;
rngARowLast = xlWorkSheet.get_Range("A1", "A" + lastACell);
objRowAValues = (System.Array) rngARowLast.Cells.Value;

ここで、ListBox に objRowAValues の値を入力しますが、ListBox は List のみを DataSource として受け入れるため、objRowAValues を文字列の List に変換する必要があります。私はこれを試しますが、うまくいきません。何か助けはありますか?

4

1 に答える 1

1

残念ながら、私はどちらかというと VB.NET 派なので、いくつかのコードを変換しました。これがすぐに使えることを願っています。ここではこの種のツールを使用していないため、テストする方法がありませんでした。

public void test()
{
    object[,] RaWData = null;

    dynamic range = xlWorkSheet.UsedRange;

    //i am unsure here about the correct order - I do not work with excel at Work, so you might have to change the following lange, if columns needs to be before rows or so
    RaWData = range.value2;

    //I am using a list here, because Lists are a lot easier to work with then simple arrays
    List<List<string>> RealData = new List<List<string>>();

    //start at 1  because the excel-delivered array do not have values at index 0 - this is the only 1-based array you will ever encounter in .net
    for (x = 1; x <= Information.UBound(RaWData, 1); x++) {
        List<string> templist = new List<string>();
        for (y = 1; y <= Information.UBound(RaWData, 2); y++) {
            templist.Add(RaWData[x, y].ToString());
        }
        RealData.Add(templist);
    }

    //you should be finished here...
}
于 2013-04-08T07:53:41.493 に答える