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

■ 「新規作成」から投稿できます。
■ マルチポストされた投稿を見つけたときは、その投稿に返信することによりご報告ください。その際は匿名で投稿し、マルチポストされている場所を併記してください。
■ スパム対策のため、メールアドレスの先頭に"_"という文字が付加されています。
RSS 2.0 RSS 2.0 | RSS 0.91 | 携帯電話用 | 自分専用のアイコンを使用するには | 掲示板への要望 | 管理人に連絡 | お気楽掲示板
■ 24時間以内に作成されたスレッドは New で表示されます。
■ 24時間以内に更新されたスレッドは UpDate で表示されます。

記事リスト ( )内の数字はレス数
Nomalユーザーフォームに埋め込んだAutoCADの変化を捉える(0) | Nomalシステムドライブ以外へのページング設定が反映されない(5) | Nomalブラウザでコピーした透過PNGを貼り付けたい(4) | Nomalforeachでループ回数を取得(2) | Nomalbitmapが保存できない(2) | Nomal特定ピクセルで画像を読み込みたい(2) | NomalDataGridViewでAlt+Enterで改行したい(2) | Nomal全角シフト中にアクセスキーが効かない(5) | NomalDataAdapter.Updateで構文エラー(6) | Nomal抽象クラスで実装したクラスの情報を知る(3) | Nomal画面遷移(モーダルとモードレス)(2) | NomalProcessクラスからbatファイル実行後、KILLできない(2) | NomalGetDirectoriesでルートを指定するとエラーになる(3) | Nomal兆億万表記の文字列を数値に変換できる?(3) | NomalLinqにおける明示的型指定の方法(3) | Nomal2つのradの数値から1つの角度を求めるコードを改善できますか?(C++)(2) | Nomalコンソールアプリで、WebView2の利用(2) | NomalEntity Frameworkは、使えるか?(2) | Nomalデータベースからのテーブル名一覧の効率的な取得方法(3) | NomalC#のlong型でオーバーフローになる(2) | Nomal正規表現のパターン表記方法(2) | NomalWebView2によるスクレ―ピング(4) | Nomalこういた物を作れますか?(2) | Nomalツールボックスにtableadapterが表示されない(1) | NomalC# Chart X軸上のグラフ表示(3) | NomalVB.NETでBluetoothデバイスの電池残量を取得する方法(3) | Nomalクリスタルレポート 明細部のサブレポート(0) | Nomal重なったPictureBox同士を透過する方法(7) | NomalWindowsフォームデザイナについて(3) | Nomalvb.netでExcelファイル操作(7) | NomalVB.NETからcmdでpingを実行した時の結果(5) | Nomalvb.netでのExcelファイルそうさ(2) | Nomalキーボード+バーコードでキーボード入力を無効にしたい(6) | NomalVB2022でクリスタルレポートが開けない(2) | Nomalファイルとして配置したマニフェストを優先したい(2) | NomalTabPageの背景色(5) | NomalC#でJpeg圧縮のTiffファイルを作成したい(4) | Nomalエクセルのみ監視ができない(2) | NomalDataGridViewのVirtualModeを有効した場合の実装方法(4) | NomalExcelの数値 -> 日付みたいな関数?(2) | Nomaljumbo icon(256x256)が存在するか知る方法(6) | NomalDrawstringでの透過文字作成(3) | NomalSpinWait()を使う理由(2) | Nomalantecedentってなんですか?(2) | Nomalワンタイムパスワードのサイトに自動ログインしてアクセストークンを得る(3) | Nomalstyle.displayだと効率悪いから違うやり方をしたいです。(5) | Nomalテーブルを順番通りに直すプログラムを外部で読み込めるようにしたいです。(4) | NomalJSONの複雑な入れ子内部の値を取りたい。(3) | Nomalグリッド表示レコードをJSONに変換(5) | Nomalシステム時計の設定(3) | NomalSeleniumで開いているページのTableを編集したい(5) | Nomalソケット通信入門 ひらがな(4) | NomalVisual Basicでエラーが出る(3) | Nomalインストーラにて、ローミングフォルダにファイルを配置したい(0) | NomalRGB値の所得(2) | Nomal時間変数(文字列)の扱い(4) | NomalVB.net からAccessDBへの接続(2) | Nomal画像のスクロール(6) | Nomalタイマーの一括処理(6) | NomalTreeViewとDataGridViewのスクロールを同期(シンクロ)させたい(4) | NomalTreeViewの現在位置とDataGridViewの現在位置を合わせたい(7) | NomalPictureBoxの画像を連続保存(11) | NomalDataGridViewの特定セルにボタンを配置する方法(5) | Nomalフォームのリサイズ時にDataGridViewが再描画されない(4) | NomalテキストボックスのValidatingイベントよりも先に発生するボタン発生イベントは何でしょう?(2) | NomalPDFをフォーム上で表示させる方法につきまして(4) | NomalDataGridViewの行ヘッダーに行番号を表示した時のエラー(4) | Nomal継承元フォームで各フォームのボタン動作を検知したい(3) | Nomalラジオボタンの一括設定(7) | NomalWindowsエクスプローラからのドラッグ&ドロップ(2) | NomalRichTextBoxのテキストをpictureBOXへ(12) | Nomalクリックイベントでexeを作成できるか(2) | Nomal作成した白黒画像をWordに貼り付けてから「図として保存」(8) | Nomalアセンブリ情報が載らない(1) | Nomal先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える(6) | Nomalc#で日付型の定義の仕方で質問があります。(2) | NomalExcel Com オブジェクトの増殖(13) | Nomal二次元マップから値の取得(1) | NomalアプリでHDMIへ出す解像度を変えたい(4) | Nomal列車の時間ごとの位置情報を表示したいです。(2) | Nomal画像の中心を基点に回転(4) | NomalDataGridViewのドロップダウンリストの表示と選択後の値を分けたい(1) | NomalVB.NetでVB6.0と同じFontを指定しても同様に印刷されない(9) | NomalタッチキーボードでIMEを自動で切替えたい(6) | NomalVSTOによるエクセルアドインのインストーラーでのアップデート(1) | NomalMP4動画を再生する方法について(5) | NomalUrlにアクセスするとダウンロードされるファイルを捕まえる(2) | NomalLableのカラー色を文字変数から変更したい(5) | NomalLabelで文字単位の背景色(7) | NomalTEXTBOXのプロパティを文字列に(7) | Nomalタブレット等でスワイプによるスクロールを実装(2) | NomalPDFをフォーム上で表示させる方法につきまして(6) | NomalChart X軸上の描画を切り替えたい(0) | NomalRichTextBoxへのドラッグ&ドロップしたExcelファイルの扱い(3) | Nomal特定のPCだけ発生する「パディングは無効なので削除できません」のエラーの原因(6) | NomalASP.NET WebApi内でXmlReader.Create(url)がタイムアウトする(4) | NomalDatagridViewでファンクションキーを止めたい(5) | Nomal表示動作が重くなる(3) | Nomalbitmapを複数スレッドで処理したい(2) | NomalLoadOptionのパラメータの意味(3) |



■記事リスト / ▼下のスレッド
■35519 / 親記事)  VB.NETでBluetoothデバイスの電池残量を取得する方法
□投稿者/ ぱんだ 一般人(4回)-(2023/09/17(Sun) 09:30:48)
  • アイコン環境/言語:[環境:Windows11 Pro 64bit 使用言語:VB.NET(Visual Studio 2022)] 
    分類:[.NET] 

    いつもお世話になっております。
    
    VB.NETでBluetoothデバイスの電池残量を取得する方法を探しているのですが、
    情報が見つからず・・・。
    なにかサンプルコード等ありますか?
    
    指定のワイヤレスイヤホンの電池残量を、タスクトレイへ数値表示したいです。
    
    Windowsの設定画面には電池残量表示されるんですが、深い階層にあり毎回見る
    のが大変で。
    
    よろしくお願いします
    
    環境  :Windows11 Pro 64bit
    使用言語:VB.NET(Visual Studio 2022)
    

違反を報告
引用返信

▽[全レス3件(ResNo.1-3 表示)]
■35520 / ResNo.1)  Re[1]: VB.NETでBluetoothデバイスの電池残量を取得する方法
□投稿者/ KOZ 一般人(29回)-(2023/09/19(Tue) 00:28:26)
  • アイコンNo35519に返信(ぱんださんの記事)
    > 指定のワイヤレスイヤホンの電池残量を、タスクトレイへ数値表示したいです。

    作った人がいるみたいです。

    https://nazenaninadesico.hatenablog.jp/entry/2021/07/17/085847

    プログラムは以下からダウンロードできます。

    http://www.moreread.net/

    .NET Framework の Windows Forms で出来ていますね。
    単独なら HttpClient で通信、Bluetooth Battery Monitor が入っていれば API を呼び出すといったことをしているようです。
    もっとも私は機器をもっていないので動作確認はできませんでしたが・・・

    Bluetooth Battery Monitor
    https://www.bluetoothgoodies.com/

    その他のアプローチとしては Windows.Devices.Bluetooth を使う方法があるようです。
    このライブラリについては、UWP で使用することが前提なので

    「デスクトップ アプリで Windows ランタイム API を呼び出す」
    https://learn.microsoft.com/ja-jp/windows/apps/desktop/modernize/desktop-to-uwp-enhance

    を参照するといいかもしれません。(私も良くわからないので)

違反を報告
引用返信
■35521 / ResNo.2)  Re[2]: VB.NETでBluetoothデバイスの電池残量を取得する方法
□投稿者/ ぱんだ 一般人(5回)-(2023/09/19(Tue) 18:13:41)
  • アイコン
    KOZさん
    返信ありがとうございます。
    プログラミング初めたての私にとっては難しい内容で理解及ばずでした。

違反を報告
引用返信
■35522 / ResNo.3)  Re[3]: VB.NETでBluetoothデバイスの電池残量を取得する方法
□投稿者/ kiku 一般人(2回)-(2023/09/19(Tue) 18:37:37)
  • アイコンNo35521に返信(ぱんださんの記事)
    > KOZさん
    > 返信ありがとうございます。
    > プログラミング初めたての私にとっては難しい内容で理解及ばずでした。

    KOZさんが提案しているのは、プログラミングしなくても
    利用する方法を含んでいます。

    方法1
    下記を試してみて、動作して満足できるなら、これを使う。
    Bluetooth Battery Monitor
    https://www.bluetoothgoodies.com/

    方法2
    下記を試してみて、動作して満足できるなら、これを使う。
    http://www.moreread.net/apps/download/BluetoothBatteryGadget.zip

    上記はできているものをそのまま使う提案。
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-3]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35518 / 親記事)  クリスタルレポート 明細部のサブレポート
□投稿者/ Inumaru 一般人(1回)-(2023/09/11(Mon) 12:49:18)
  • アイコン環境/言語:[Windows10 pro Viauslbasic 2013] 
    分類:[.NET] 

    VisualBasic 2013 でクリスタルレポートを利用して帳票発行を行おうとしております。

    帳票
    メインとなるレポートに顧客名を出力
    メインとなるレポートの顧客名をグループヘッダとして配置
    メインとなるレポートの明細部にサブレポートを配置
    条件に一致する場合にサブレポート(明細)を出力

    基本的に問題なく動作するのですが、
    以下の点が解決できていない状況です。

    ★改善したい点
     メインレポートの1ページ目(グループヘッダの切り替わり毎)に
     サブレポートが出力されないレポートが必ず出力される。
     ※メインレポートのみ出力されたレポートが必ず出力される。


    どなたか原因などが分かる方がいらっしゃいましたらご教授頂けますと
    幸いです。

違反を報告
引用返信



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35510 / 親記事)  重なったPictureBox同士を透過する方法
□投稿者/ 本体は眼鏡 一般人(4回)-(2023/09/05(Tue) 08:53:37)
  • アイコン環境/言語:[Windows 10 Pro 64bit/VB.net] 
    分類:[.NET] 

    VB.net(Microsoft Visual Studio Community 2022 (64 ビット) )を使用しています。

    お世話になります。
    またまたお尋ねしたい事があり、ご教示いただけますと幸いです。

    重なっているPictureBoxにフォームの背景色ではなくて、画像の重なっている部分を表示させたいのですが、実現出来ずに困っております。

    添付画像の様に、Windowsフォームデザイナ上にPictureBox同士を隣合せで配置しており、
    Imageプロパティに、背景を透過処理したGIF画像を設定しています。

    https://teratail.com/questions/163912
    を参考にし、どちらのPictureBoxもBackgroundColorプロパティにはTransparentを設定済みです。

129×118
イメージ
1693871617.jpg
/9KB
違反を報告
引用返信

▽[全レス7件(ResNo.3-7 表示)]
■35513 / ResNo.3)  Re[2]: 重なったPictureBox同士を透過する方法
□投稿者/ KOZ 一般人(26回)-(2023/09/05(Tue) 12:10:16)
  • アイコンNo35512に返信(KOZの記事)
    補足です。
    Controls コレクションは Z オーダー順に並んでいるので、後ろから列挙して自分が出てきたら終了です。
    ただ、SetWindowPos で並びを変えてしまうと合わなくなるかもしれないので、API で列挙したほうがいいかもしれません。
違反を報告
引用返信
■35514 / ResNo.4)  Re[2]: 重なったPictureBox同士を透過する方法
□投稿者/ 本体は眼鏡 一般人(5回)-(2023/09/06(Wed) 08:38:37)
  • アイコンNo35511に返信(魔界の仮面弁士さんの記事)
    す。

    魔界の仮面弁士 様 お返事ありがとうございます。
    返信遅くなり申し訳ありません。

    > そのため、透過(あるいは半透明の)画像を複数重ね合わせて描画したい場合は、
    > PictureBox を複数枚使うのではなく、単一の PictureBox 上に
    > 自前で複数の画像を Graphics.DrawImage することで実現します。
    一つ一つのPictureBoxが機器の死活監視状態を表しており、
    300個以上あるため、私一人で実装するのは納期的にもちょっと難しそうです…
    プロパティの変更で出来る物かと安易に考えていました。
    今回はPictureBoxのサイズを小さくし、重ならないギリギリで配置することで回避しようと思います。
    せっかく教えて頂いたのに申し訳ありません…

    > https://dobon.net/vb/dotnet/graphics/index.html
    こちら折れ線グラフ作成等の際にとても助かりました。
    ありがとうございます。

    > 要件によっては、BackgroundImage と Image と Paint イベントの 3 つを
    > 組み合わせて使うこともありますね。
    今のプログラムが完成したら、頂いたページを参照しながらサンプルプログラムを作成し、今後の参考資料にしたいと思います。
解決み!
違反を報告
引用返信
■35515 / ResNo.5)  Re[3]: 重なったPictureBox同士を透過する方法
□投稿者/ 本体は眼鏡 一般人(6回)-(2023/09/06(Wed) 08:40:23)
  • アイコン2023/09/06(Wed) 14:17:22 編集(投稿者)
    2023/09/06(Wed) 14:17:13 編集(投稿者)

    No35513に返信(KOZさんの記事)
    > ■No35512に返信(KOZの記事)

    KOZ 様 お返事・サンプルソースのご提供ありがとうございます。

    プロパティ設定程度で実現出来るかと安易に考えていました。
    頂いたソースを理解して、私一人で実装するには納期的にもちょっと難しそうです…

    これまで何度かカスタムコントロールの作成に挫折してきましたが、
    今のプログラムが完成したら、頂いたソースを基にカスタムコントロールに挑戦してみたいと思います。
解決み!
違反を報告
引用返信
■35516 / ResNo.6)  Re[4]: 重なったPictureBox同士を透過する方法
□投稿者/ KOZ 一般人(27回)-(2023/09/06(Wed) 18:19:00)
  • アイコンNo35515に返信(本体は眼鏡さんの記事)
    > 頂いたソースを理解して、私一人で実装するには納期的にもちょっと難しそうです…
    >
    > これまで何度かカスタムコントロールの作成に挫折してきましたが、
    > 今のプログラムが完成したら、頂いたソースを基にカスタムコントロールに挑戦してみたいと思います。

    VisualStyle が無効でも透過できるよう作りましたが、VisualStyle が有効で BackColor = Color.Transparent のときのみ透過するのであれば、親の描画は PictureBox に任せて不要になるので、コードはかなり短くなります。
    挑戦するときは考慮してみてください。
解決み!
違反を報告
引用返信
■35517 / ResNo.7)  Re[5]: 重なったPictureBox同士を透過する方法
□投稿者/ KOZ 一般人(28回)-(2023/09/09(Sat) 11:50:05)
  • アイコン
    2023/09/09(Sat) 11:50:38 編集(投稿者)
    
    Windows 8 から子ウインドウがレイヤードウインドウになれるので、アプリケーションマニュフェストを追加して
    
          <!-- Windows 8 -->
          <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
    
    のコメントアウトを解除すると、簡単に透過できますね。
    
    # GetWindowLong/SetWindowLong を使っているのは手抜きです。(長くなるので)
    # プロセスが 64bit なら GetWindowLongPtr,SetWindowLongPtr を使うのが正式なやり方。
    # 64bit で SetWindowLong を使うと成功しても戻り値がゼロになってしまいます。
    
    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        Private Const WS_EX_LAYERED = &H80000
        Private Const GWL_EXSTYLE = -20
        Private Enum LWA
            COLORKEY = &H1
            ALPHA = &H2
        End Enum
    
        Private Sub PictureBox_HandleCreated(sender As Object, e As EventArgs) _
                    Handles PictureBox1.HandleCreated,
                            PictureBox2.HandleCreated
            Dim pic = DirectCast(sender, PictureBox)
            pic.Image = My.Resources.megane_hikaru_woman
            pic.SizeMode = PictureBoxSizeMode.Zoom
            pic.BackColor = Color.Gray
            Dim dwStyle = GetWindowLong(pic.Handle, GWL_EXSTYLE)
            dwStyle = dwStyle Or WS_EX_LAYERED
            SetWindowLong(pic.Handle, GWL_EXSTYLE, dwStyle)
            SetLayeredWindowAttributes(
                    pic.Handle, ColorTranslator.ToWin32(pic.BackColor),
                    0, LWA.COLORKEY)
        End Sub
    
        <DllImport("user32.dll")>
        Private Shared Function GetWindowLong(
                    hWnd As IntPtr, nIndex As Integer) As Integer
        End Function
    
        <DllImport("user32.dll")>
        Private Shared Function SetWindowLong(
                    hWnd As IntPtr, nIndex As Integer,
                    dwNewLong As Integer) As Integer
        End Function
    
        <DllImport("user32.dll")>
        Private Shared Function SetLayeredWindowAttributes(
                    hWnd As IntPtr, crKey As Integer,
                    bAlpha As Byte, dwFlags As LWA) As Boolean
        End Function
    
    End Class
    
    透過画像のまわりに BackColor が残ってしまいますが、目立たない色を設定しておくといいです。
    
    
    

解決み!
268×285 => 235×250
イメージ
layeredWindow.jpg
/15KB
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-7]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35504 / 親記事)  Windowsフォームデザイナについて
□投稿者/ 本体は眼鏡 一般人(1回)-(2023/09/01(Fri) 16:52:51)
  • アイコン環境/言語:[Windows 10 Pro 64bit/VB.net ] 
    分類:[.NET] 

    VB.net(Microsoft Visual Studio Community 2022 (64 ビット) )を使用しています。

    初めまして。お世話になります。

    vs2022のフォームデザイナ上でコントロールを移動やサイズ変更等行うと、
    一部のフォームで、form.Designer.vbの内容が勝手に書き換わり、
    『BC30035 構文エラーです。』と出ます。
    毎回置換して修正しているのですが、改善策をご存知でしたらご教示お願い致します。

    以下ソースの一部
    変更される前
    CType(Me.dgvDataGridView2, Global.System.ComponentModel.ISupportInitialize).BeginInit()

    変更された後
    (CType(Me.dgvDataGridView2, Global.System.ComponentModel.ISupportInitialize)).BeginInit()

    通常とは異なる環境として
    VB6→VB.netへのコンバージョンを行っております。
    vb6.0→vb2008→vs2022の手順でアップグレードウィザードを使用し、
    form.Designer.vbとform.vbを既存の項目として追加にてプロジェクトに加えてます。
違反を報告
引用返信

▽[全レス3件(ResNo.1-3 表示)]
■35507 / ResNo.1)  Re[1]: Windowsフォームデザイナについて
□投稿者/ 魔界の仮面弁士 大御所(1564回)-(2023/09/01(Fri) 17:36:00)
  • アイコンNo35504に返信(本体は眼鏡さんの記事)
    > (CType(Me.dgvDataGridView2, Global.System.ComponentModel.ISupportInitialize)).BeginInit()

    検索したところ、下記の記事がヒットしました。
    少し古い記事ですが、Visual Studio 2022 における
    バージョン 17.5 系列の不具合だったもので、その後は
    17.6.0 以降のバージョンで解消されたと書かれています。
    https://developercommunity.visualstudio.com/t/VS-designer-generated-code-changed-with-/10316923

    まずは、手元の Visual Studio 2022 の正確なバージョンを確認してください。
    最新版になっていないから不具合が起きているのか、それとも、
    最新版にすることで過去の不具合が再発したのかを切り分けるために必要です。

    直近の履歴によると
     2023/08/29 に v17.7.3
     2023/08/08 に v17.8.0 Preview 1
    がリリースされているようです。
違反を報告
引用返信
■35508 / ResNo.2)  Re[2]: Windowsフォームデザイナについて
□投稿者/ 本体は眼鏡 一般人(2回)-(2023/09/01(Fri) 17:46:52)
  • アイコン魔界の仮面弁士 様

    お返事ありがとうございます。

    > まずは、手元の Visual Studio 2022 の正確なバージョンを確認してください。
    確認した所、ご指摘の通りVersion 17.5.4でした…
    早速アップデートをして動作を確認してみたいと思います。
    動作確認の結果は改めて報告させて頂きます。

違反を報告
引用返信
■35509 / ResNo.3)  Re[3]: Windowsフォームデザイナについて
□投稿者/ 本体は眼鏡 一般人(3回)-(2023/09/01(Fri) 18:17:24)
  • アイコンお世話になります。

    Version 17.7.3に更新した所、現象が発生していた8画面全てで、
    再現されなくなりました。

    これをもって解決済みとさせて頂きます。

    魔界の仮面弁士 様 本当にありがとうございました。
    今後ともよろしくお願いいたします。

解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-3]



■記事リスト / ▲上のスレッド
■35490 / 親記事)  vb.netでExcelファイル操作
□投稿者/ Excel難しい 一般人(1回)-(2023/08/22(Tue) 14:55:20)
  • アイコン環境/言語:[vb.net .NET Franework 4.7.2] 
    分類:[.NET] 

    どうしてもタスクマネージャーのバックグラウンドプロセスにExcelが残ってしまいます。
    何か変な所ありますでしょうか?

    Dim ex As New Microsoft.Office.Interop.Excel.Application
    Dim wb As Microsoft.Office.Interop.Excel.Workbook = ex.Workbooks.Open(txtpath.Text)

    wb.Close(False)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wb)
    wb = Nothing

    ex.Quit()
    System.Runtime.InteropServices.Marshal.ReleaseComObject(ex)
    ex = Nothing

    MsgBox(“作成完了”)
違反を報告
引用返信

▽[全レス7件(ResNo.3-7 表示)]
■35493 / ResNo.3)  Re[1]: vb.netでExcelファイル操作
□投稿者/ 魔界の仮面弁士 大御所(1559回)-(2023/08/22(Tue) 15:37:00)
  • アイコンNo35490に返信(Excel難しいさんの記事)
    No35487 の 独学学生さんとは別の方ですか?

    > Dim ex As New Microsoft.Office.Interop.Excel.Application
    これは良いとして

    > Dim wb As Microsoft.Office.Interop.Excel.Workbook = ex.Workbooks.Open(txtpath.Text)
    ここが違いますね。 No35488 で Hongliang さんも書かれているように:

    Dim books As Microsoft.Office.Interop.Excel.Workbooks = ex.Workbooks
    Dim wb As Microsoft.Office.Interop.Excel.Workbook = books.Open(txtpath.Text)

    のように、COM オブジェクトごとに別々の変数に保持してください。

    > wb.Close(False)
    > System.Runtime.InteropServices.Marshal.ReleaseComObject(wb)

    なので、Workbooks も解放せねばなりません。
    System.Runtime.InteropServices.Marshal.ReleaseComObject(books)

    > wb = Nothing
    > ex.Quit()
    > System.Runtime.InteropServices.Marshal.ReleaseComObject(ex)
    > ex = Nothing
違反を報告
引用返信
■35499 / ResNo.4)  Re[2]: vb.netでExcelファイル操作
□投稿者/ Excel難しい 一般人(6回)-(2023/08/23(Wed) 07:03:10)
  • アイコン独学学生と同じです!!

    では、シートを指定したい場所は

    Dim sheet As Microsoft.Office.Interop.Excel.Worksheets= ex.Worksheets

    Dim sh As Microsoft.Office.Interop.Excel.Worksheet =sheet(“発注”)

    になるって事でしょうか??
違反を報告
引用返信
■35500 / ResNo.5)  Re[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 に切り替えることも検討)
違反を報告
引用返信
■35502 / ResNo.6)  Re[4]: vb.netでExcelファイル操作
□投稿者/ Excel難しい 一般人(7回)-(2023/08/24(Thu) 11:13:46)
  • アイコン度々申し訳ありません。
    ワークブックとワークシートはおそらく解放できていると思うのですがまだプロセスが残ってしまいます。

    Dim lastRow As Integer = sh.Cells(sh.Rows.Count, "B").End(Microsoft.Office.Interop.Excel.XlDirection.xlUp).row
    とrange.ClearContents()をコメントにし、
    range = Cells.Range("B5:I" & lastRow)をrange = Cells.Range("B5:I5")に変更するとプロセスが残らず終了できるので、lastRowかrange.ClearContents()のどちらかが解放漏れしていてプロセスが残ってしまっていると考えて居るのですが、解放の仕方が分からない状態です。
    お力を貸してください。

    Private Sub btn作成_Click(sender As Object, e As EventArgs) Handles btn作成.Click
    If txtPath.Text = "" Then
    Exit Sub
    End If

    Dim str As String = ""
    Dim strCount = 0

    Dim ex As New Microsoft.Office.Interop.Excel.Application
    Dim books As Microsoft.Office.Interop.Excel.Workbooks = ex.Workbooks
    Dim wb As Microsoft.Office.Interop.Excel.Workbook
    Dim sheets As Microsoft.Office.Interop.Excel.Sheets
    Dim sh As Microsoft.Office.Interop.Excel.Worksheet

    Dim Cells As Microsoft.Office.Interop.Excel.Range
    Dim range As Microsoft.Office.Interop.Excel.Range

    Try
    For rw As Integer = 0 To dgv.RowCount - 1
    If strCount = 0 Then
    wb = books.Open(txtPath.Text)
    sheets = wb.Worksheets
    sh = sheets("発注一覧")
    Cells = sh.Cells
    strCount = strCount + 1

            'ファイル内のセル初期化
    Dim lastRow As Integer = sh.Cells(sh.Rows.Count, "B").End(Microsoft.Office.Interop.Excel.XlDirection.xlUp).row
    If lastRow >= 5 Then
    range = Cells.Range("B5:I" & lastRow)
    range.ClearContents()
    End If

    End If

    strCount = strCount + 1
    End If
    Next

    wb.Save()
    wb.Close(False)
    ex.Quit()


    Catch exc As Exception
    Finally
    If Cells IsNot Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(Cells)
    End If
    If range IsNot Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(range)
    End If
    If sheets IsNot Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets)
    End If
    If sh IsNot Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(sh)
    End If
    If books IsNot Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(books)
    End If
    If wb IsNot Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wb)
    End If
    If ex IsNot Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(ex)
    End If

    Cells = Nothing
    range = Nothing
    sheets = Nothing
    sh = Nothing
    books = Nothing
    wb = Nothing
    ex = Nothing

    GC.Collect()
    GC.WaitForPendingFinalizers()

    btn作成.Enabled = True

    If strCount <> 0 Then
    MsgBox(“作成完了”)
    End If
    End Try

    End Sub
違反を報告
引用返信
■35503 / ResNo.7)  Re[5]: vb.netでExcelファイル操作
□投稿者/ 魔界の仮面弁士 大御所(1561回)-(2023/08/24(Thu) 14:16:09)
  • アイコン2023/08/24(Thu) 17:37:12 編集(投稿者)

    No35502に返信(Excel難しいさんの記事)
    > Dim lastRow As Integer = sh.Cells(sh.Rows.Count, "B").End(Microsoft.Office.Interop.Excel.XlDirection.xlUp).row

    先の回答がまるで反映されていないですよね…?
    Range オブジェクトすべてを変数にとり、使用後に廃棄しましょう。

    'Dim lastRow As Integer = sh.Cells(sh.Rows.Count, "B").End(Microsoft.Office.Interop.Excel.XlDirection.xlUp).row
    Dim cells = sh.Cells
    Dim rows = sh.Rows
    Dim rng = cells(rows.Count, "B")
    Dim rngEnd = rng.End(Microsoft.Office.Interop.Excel.XlDirection.xlUp)

    Dim lastRow As Integer = rngEnd.Row

    Marshal.RelaseComObject(rngEnd)
    Marshal.RelaseComObject(rng)
    Marshal.RelaseComObject(rows)
    Marshal.RelaseComObject(cells)

    正直なところ、生の Excel ライブラリを直接扱うのは、COM リソースの管理が面倒なので、
    先に紹介したような、Managed リソースで管理できるライブラリを使った方が楽だと思いますよ。


    > range = Cells.Range("B5:I" & lastRow)を
    この処理自体には何の問題もありません。
    実際のところ、
     Dim lastRow As Integer = 5
     range = Cells.Range("B5:I" & lastRow)
    であれば、問題は出ないですよね?

    問題があったのは、lastRow を求めるための先の手続きです。


    > Private Sub btn作成_Click(sender As Object, e As EventArgs) Handles btn作成.Click
    strCount が何をカウントしているのかの意図が不明瞭ですが、
    提示されたコードでは「If 〜 Then」よりも「End If」の方が多く、文法的に意味が通りません。
    正しいコードを提示しましょう。


    それと、COM オブジェクトの扱いに根本的な誤解があるようです。
     Dim o1 = sheet1.Cells
     Dim o2 = sheet1.Cells
    この場合、o1 と o2 は同一のオブジェクトを指しているように見えますが、
    実際は別物であり、 If o1 Is o2 Then は False となります。

    なのでこのケースでは、
     Marshal.ReleaseComObject(o2)
     Marshal.ReleaseComObject(o1)
    のように、それぞれを解放せねばなりません。

    それゆえに
     Dim o As Excel.Range = Nothing
     For n = 1 To 2
      o = sheet1.Cells
      :
     Next
     Marshal.ReleaseComObject(o)
    のような再代入処理が行われると、Range オブジェクトの解放漏れに繋がります。
    ※Range 以外の COM オブジェクト(Workbooks とか Workbook とか Sheets とか Worksheet とか)も同様です。

    ただし、
     For n = 1 To 2
      Dim o As Excel.Range = sheet1.Cells
      :
      Marshal.ReleaseComObject(o)
     Next
    のように、取得 → 解放の手続きをその都度行うのであれば、問題ありません。
    (とはいえ、何度も取得しなおす方法では、実行コストが高くなってしまいますが)


    > For rw As Integer = 0 To dgv.RowCount - 1
    >  If strCount = 0 Then
    >   wb = books.Open(txtPath.Text)
    >   sheets = wb.Worksheets
    >   sh = sheets("発注一覧")
    ということで、この書き方は NG 。

    そもそも、COM オブジェクトの問題が無かったとしても、
    このコードもあまりに不自然というものです。

    ループ内で、txtPath.Text が変化するわけでは無いのですから、
    毎回、COM オブジェクトを再取得する意味は無いはずです。
    ループの外で処理すれば済む話でしょう。

    Dim wb = books.Open(txtPath.Text)
    Dim sheets = wb.Worksheets
    Dim sh = sheets("発注一覧")
    For rw = 0 To dgv.RowCount - 1
      :
    Next
    Marshal.ReleaseComObject(sh)
    Marshal.ReleaseComObject(sheets)
    wb.Save()
    wb.Close(False)
    Marshal.ReleaseComObject(wb)
    ex.Quit()
    Marshal.ReleaseComObject(ex)


    それにしても、『For rw As Integer = 0 To dgv.RowCount - 1』って何の意味があるのでしょうか?
    dgv が DataGridView であるというのは想像がつきますが、
    ループ内で変数 rw が一度も使われていませんし、ループさせる意味が皆無に見えるのですが。
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-7]






Mode/  Pass/


- Child Tree -

2024/07/23(Tue) 16:30:46 に作成されたキャッシュを表示しています。
生のデータを表示する | キャッシュを最新にする