DOBON.NET DOBON.NETプログラミング掲示板過去ログ

EXCEL起動を1つにしたい(シートの移動が出来ない為)

環境/言語:[.NET F1.1 VB.NET Win2000]
分類:[.NET]

お世話になります。
以下、ご教示をお願いします。
「SearchPath」フォルダより、「*A.csv」のファイルの中身を読んで、
クリップボードにコピーし、EXCELにキー送信で貼り付けることをします。
下のメソッドを使うと、Book毎にEXCELが起動してしまいます。
どのようにしたら、1つのEXCELにBookが複数作成されるのでしょうか?

  ▼呼び出し▼
ExcelClipOut(SearchPath, "A", 1, 1)
ExcelClipOut(SearchPath, "B", 2, 2)
ExcelClipOut(SearchPath, "C", 3, 3)
  ▲ここまで▲

Private Sub ExcelClipOut(ByVal SearchPath As String, ByVal ABC As String, ByVal SheetNo As Integer, ByVal Cnt As Integer)

'必要な変数を宣言する
Dim stPrompt As String = String.Empty
'.txt のファイルを列挙する
For Each stFilePath As String In System.IO.Directory.GetFiles(SearchPath + "\", "*" & ABC & ".csv")
stPrompt &= stFilePath & System.Environment.NewLine
Next stFilePath
'txtを読む
Dim TextData As String
Dim Reader As New IO.StreamReader(stPrompt, System.Text.Encoding.GetEncoding(932))
TextData = Reader.ReadToEnd
Reader.Close()
'タブ形式でクリップボードへ
Dim data As DataObject = New DataObject
data.SetData(TextData.Replace(",", vbTab))
Clipboard.SetDataObject(data, True)
'エクセルへ貼り付け
If Cnt = 1 Then
Excel = CType(CreateObject("Excel.Application"), Excel.Application)
ExcelBook = CType(Excel.Workbooks.Add, Excel.Workbook)
End If
ExcelBook.Worksheets(SheetNo).Activate()
ExcelSheet = CType(ExcelBook.Worksheets(SheetNo), Excel.Worksheet)
ExcelSheet.Application.Visible = True
ExcelSheet.Range("A1").Select()
System.Windows.Forms.SendKeys.SendWait("%{E}{P}")

End Sub

以上
■No15906に返信(普通の会社員さんの記事)
> 下のメソッドを使うと、Book毎にEXCELが起動してしまいます。
> どのようにしたら、1つのEXCELにBookが複数作成されるのでしょうか?

下記スレッドが参考になるかと思います。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=29237&forum=7
じゃんぬねっとさん
アドバイスありがとうございます。
エクセルが起動しているかは、
Process.GetProcessByName("Excel").Length
で分りますが、起動している場合に、
Excel = CType(CreateObject("Excel.Application"), Excel.Application)
を抜かすと怒られます。
お助け願います。
■No15948に返信(普通の会社員さんの記事)
> エクセルが起動しているかは、
> Process.GetProcessByName("Excel").Length
> で分りますが、

確認する必要はないと思います。

> 起動している場合に、
> Excel = CType(CreateObject("Excel.Application"), Excel.Application)
> を抜かすと怒られます。
> お助け願います。

すみません、どうも提示したリンクが悪かったみたいです。(;^-^)
(しっかりと読んで、意図を理解しないといけませんね...)

当初の質問は、

> > 下のメソッドを使うと、Book毎にEXCELが起動してしまいます。
> > どのようにしたら、1つのEXCELにBookが複数作成されるのでしょうか?

でしたよね。(^^)

これは Excel.Application の WorkBooks に Book を Add していけば、Excel.Application 自体は単独のままですよね。
Excel.Application を新たに作成する時点でおかしいということになります。

それと、COM オブジェクトを使用していますが、
「暗黙の参照」がなされており、解放するタイミングを逃しています。
これでは、メモリリークを起こす可能性があります。
(結果 Excel のプロセスが居残ります)

これに関しては、以下を参考にしてください。

 COM オブジェクトを解放する
 http://jeanne.wankuma.com/tips/programing/releasecom.html

それと、キーによる送信の貼り付けは、動作の保証がないため危険です。
たとえば、その直前に別のウィンドウをアクティブにされたら破綻します。

よって、自分で読んで自分で貼り付ける実装が望ましいでしょう。
今の実装では、とても運用に耐えられないと思います。
じゃんぬねっとさん
レスありがとうございます。

COMオブジェクトについて、勉強不足ですみません。
調べて見ます。

※クリップボードからの貼り付けは、以下に変更しました。
ExcelBook.Worksheets(SheetNo).Paste()

以上
■No15953に返信(普通の会社員さんの記事)
> COMオブジェクトについて、勉強不足ですみません。
> 調べて見ます。

はい、ちゃんと調べれば大丈夫だと思います。

> ※クリップボードからの貼り付けは、以下に変更しました。
> ExcelBook.Worksheets(SheetNo).Paste()

これも、Worksheets と Worksheet が暗黙的に参照されています。
せっかくなので、これを例に説明だけしておきます。

Dim xlSheets As Excel.Sheets = xlExcelBook.Worksheets
Dim xlSheet As Excel.Worksheet = DirectCast(xlSheets(SheetNo), Excel.Worksheet)

として、"参照" を変数に取っておき、(暗黙ではなく、明示的に参照する)
ReleaseComObject しなければなりません。

ということです。

これは他のオブジェクトも同様です。
WorkSheets や WorkBooks など、コレクションを表すオブジェクトに特に注意してください。

DOBON.NET | プログラミング道 | プログラミング掲示板