|
■No81762 (Artor さん) に返信 > Dim row As Long = 1
As Integer(Int32) に書き換えることをお奨めします。 As Long(Int64) でも間違いというわけでは無いのですが、 行数は最大でも &H100000 行(1,048,576)なので、Int32 で十分なはず。
※ Int32.MaxValue = 2,147,483,647
64bit 版 Excel なら、Int64 値を直接扱えるのですが、 32bit 版 Excel では、Variant の内部処理形式としてしか Int64 値を扱えないため、不都合を生じる事が稀にあるので。
> objBook = objExcel.Workbooks.Add(strFilePath & strFileName)
これが NG なのは既出ですね。 Workbooks コレクションも解放対象です。
> objSheet1 = objSheets.Item(1) > objSheet2 = objSheets.Item(2)
Sheets コレクションのインデクサは Object 型を返しますので、 DirectCast を併用した方が丁寧です。
> objRange2 = objSheet2.Cells > Do While Not String.IsNullOrEmpty(objRange2(row, 1).text)
この場合、 objRange3 = DirectCast(objRange2(row, 1), Excel.Range) s = objRange3.Text として、objRange3 の解放が必要になります。
ただし A1:A5 のように連続している領域を読み取るのであれば、 No81786 のように複数セルをまとめて配列として受け取った方が効率が良いでしょう。
> 'シート2名前定義からシート1の読取箇所を特定 > strName = objRange2(row, 1).text
ここも同様ですね。 「objRange2(row, 1)」が返す Range オブジェクトも解放対象です。
> 'データテーブルにカラム追加 > dt.Columns.Add(strName, Type.GetType("System.String"))
同じ列名が二重登録されると DuplicateNameException の例外になりますので、 No81786 では、Sheet2 に同じ名前が記録されていた場合についても対処しています。
もし、存在しない名前が記録されていた場合にも対処するのであれば、 Names コレクションを併用すると良いでしょう。
> readRow = readRow + 1
先ほどの「Dim row As Long = 1」とは別物でしょうか? readRow は未定義ですし、row は未使用なようですが…。
> 'データテーブルに行追加 > dt.Rows.Add(dr)
追加した直後の DataRow は、行の状態が Added になるため、 No81786 では、AcceptChanges メソッドを呼んで Unchanged にしています。
> System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objRange1)
これは Final 付きでも Final 無しでも構いません。 今回のようなケースであれば、ReleaseComObject でも十分ですね。
たとえば Range プロパティの引数に Range オブジェクトを渡すような場合、 内部的に参照カウントが増加することがあるため、FinalReleaseComObject を 呼ばないと解放されないことがあります。
> 'ガーベージコレクタ動作 > System.GC.Collect()
文書によって、ガーベージ、ガーベジ、ガベージなどと表記ゆれがありますが、 Microsoft としては、VB や C# に対してはガベージ表記で統一しているようです。
なお、オブジェクト参照が残っている状態で GC.Collect を呼んだ場合、 むしろ解放処理が遅れる要因にもなりえます。GC に任せるのも選択肢の一つですが、 No81786 では意図的に、GC.Collect を呼ばないコードとして記述しています。
|