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

■35500 / 3階層)  vb.netでExcelファイル操作
□投稿者/ 魔界の仮面弁士 大御所(1560回)-(2023/08/23(Wed) 15:12:12)
  • アイコン2023/08/24(Thu) 14:05:02 編集(投稿者)

    No35499に返信(Excel難しいさんの記事)
    > 独学学生と同じです!!
    ここの掲示板の利用ルールには
     「一貫した名前を使用し、投稿によって名前を変えないでください」
     「投稿者名を変えて投稿できないことになっています」
    と明記されています。無暗に変更しないようにしましょう。
    https://dobon.net/vb/bbs/index.html#manners


    COM オブジェクトの Excel を直接参照設定して使うのは、バージョン不一致時の互換性問題や、
    オブジェクトの解放手順の煩雑さの点や、現状ではあまりおすすめできません。
    利用者がストアアプリ版の Office を利用していると呼び出せませんし。

    要件次第では ClosedXml / NetOffice / SpreadSheetLight / などを用いることも検討してみてください。
    「実行環境に Excel 本体が無くても呼び出せる」というメリットもあります。



    > では、シートを指定したい場所は
    毎回 Microsoft.Office.Interop.Excel を書くのは煩わしいので、
    通常は、ファイル先頭に Imports ステートメントを書いて省略します。
    (もしくは、プロジェクト単位のユーザーインポートを使う手法もある)
    実際には案2を使っている事例が多いですね。


    <案1>
    Imports Microsoft.Office.Interop
    Public Class Form1
     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Dim ex As New Excel.Application() With { .Visible = True }


    <案2>
    Imports Excel = Microsoft.Office.Interop.Excel
    Public Class Form1
     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Dim ex As New Excel.Application() With { .Visible = True }


    > Dim sheet As Microsoft.Office.Interop.Excel.Worksheets= ex.Worksheets
    Sheets や Worksheets といったコレクション オブジェクトは、「複数形」の型名なので
    sheet といった「単数形」の変数名にすると、後で読むときにややこしくないですか…?

    それはさておき、外部からアクセスする場合は、Application の Worksheets プロパティを使用しないでください。
    Worksheets にアクセスする前に、Workbooks に対して Add か Open を呼び出して
    Workbook オブジェクトを取得し、そのあとで Worksheets プロパティにアクセスします。

    > Dim sh As Microsoft.Office.Interop.Excel.Worksheet =sheet(“発注”)
    Worksheets プロパティはその戻り値として
    実は Worksheets 型ではなく Sheets 型のオブジェクトを返します。
    型が異なるため、Worksheets 型には代入できません。

    そのため .NET から扱う場合は
     Dim sheet As Excel.Sheets = book.Worksheets
    のように書くことになります。

    とはいえ、VB2008 以降なら型推論が使えるので、単に
     Dim sheets = book.Worksheets
    と書くのが簡単でしょう。

    Worksheet に関しては、そこから
     Dim sheet1 = DirectCast(sheets("Sheet1"), Excel.Worksheet)
    とします。単に
     Dim sheet1 = sheets("Sheet1")
    にしてしまうと、As Object になってしまうため、DirectCast で本来の型に戻します。


    そのほか、間違えやすいのが Cells プロパティ。

    VBA においては
     sheet1.Cells(1, 1).Value = 123
    などと書けますが、Cells プロパティは実は「引数を持たないプロパティ」であり、
    内部的には、既定のプロパティを通じて
     sheet1.sheet1.Cells.[_Default](1,1).Value = 123
    に相当する VBA コードになります。

    さらに、Range オブジェクトもまた、COM のオブジェクトであるため、
    上記の VBA コードを .NET の世界で扱うときには、
     Dim cells As Excel.Range = sheet1.Cells
     Dim cell1 As Excel.Range = cells(1, 1)
     cell1.Value = 100
     Marshal.ReleaseComObject(cell1)
     Marshal.ReleaseComObject(cells)
    という手続きを踏まねばなりません。


    もう一つ厄介なのかが「暗黙の型変換」。
    Excel の幾つかのメソッドやプロパティには、COM オブジェクトを引数に持つメンバーがありますが、
    この時に、明示的な型ではなく、汎用型の As Object な引数で受けわたしてしまうと、
    その時点で COM の参照カウントが増大し、Marshal.ReleaseComObject を呼んでも
    即時に解放されにくくなってしまうことがあります。
    (Object 型ではなく、本来の型の変数を引数に渡すのであればセーフ)

    参照カウントが増大していた場合、Marshal.ReleaseComObject の呼び出し後、
    戻り値が 0 にならないため、そこで判断することができます。
    (要件次第では、FinalReleaseComObject に切り替えることも検討)
違反を報告
削除キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←Re[2]: vb.netでExcelファイル操作 /Excel難しい →Re[4]: vb.netでExcelファイル操作 /Excel難しい
 
上記関連ツリー

Nomalアイコン vb.netでExcelファイル操作 / Excel難しい (23/08/22(Tue) 14:55) #35490
Nomalアイコン Re[1]: vb.netでExcelファイル操作 / Hongliang (23/08/22(Tue) 15:04) #35491
│└Nomalアイコン Re[2]: vb.netでExcelファイル操作 / Excel難しい (23/08/22(Tue) 15:13) #35492
Nomalアイコン Re[1]: vb.netでExcelファイル操作 / 魔界の仮面弁士 (23/08/22(Tue) 15:37) #35493
  └Nomalアイコン Re[2]: vb.netでExcelファイル操作 / Excel難しい (23/08/23(Wed) 07:03) #35499
    └Nomalアイコン vb.netでExcelファイル操作 / 魔界の仮面弁士 (23/08/23(Wed) 15:12) #35500 ←Now
      └Nomalアイコン Re[4]: vb.netでExcelファイル操作 / Excel難しい (23/08/24(Thu) 11:13) #35502
        └Nomalアイコン Re[5]: vb.netでExcelファイル操作 / 魔界の仮面弁士 (23/08/24(Thu) 14:16) #35503

All 上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信

Mode/  Pass/


- Child Tree -