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

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

記事リスト ( )内の数字はレス数
Nomal全角シフト中にアクセスキーが効かない(5) | NomalDataAdapter.Updateで構文エラー(6) | Nomal抽象クラスで実装したクラスの情報を知る(3) | NomalProcessクラスからbatファイル実行後、KILLできない(2) | Nomal画面遷移(モーダルとモードレス)(2) | Nomal兆億万表記の文字列を数値に変換できる?(3) | NomalGetDirectoriesでルートを指定するとエラーになる(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からcmdでpingを実行した時の結果(5) | Nomalvb.netでExcelファイル操作(7) | Nomalvb.netでのExcelファイルそうさ(2) | Nomalキーボード+バーコードでキーボード入力を無効にしたい(6) | Nomalファイルとして配置したマニフェストを優先したい(2) | NomalTabPageの背景色(5) | NomalVB2022でクリスタルレポートが開けない(2) | NomalC#でJpeg圧縮のTiffファイルを作成したい(4) | Nomalエクセルのみ監視ができない(2) | NomalDataGridViewのVirtualModeを有効した場合の実装方法(4) | NomalExcelの数値 -> 日付みたいな関数?(2) | NomalDrawstringでの透過文字作成(3) | Nomaljumbo icon(256x256)が存在するか知る方法(6) | 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) | NomalVB.net からAccessDBへの接続(2) | Nomal時間変数(文字列)の扱い(4) | Nomal画像のスクロール(6) | Nomalタイマーの一括処理(6) | NomalTreeViewとDataGridViewのスクロールを同期(シンクロ)させたい(4) | NomalTreeViewの現在位置とDataGridViewの現在位置を合わせたい(7) | Nomalフォームのリサイズ時にDataGridViewが再描画されない(4) | NomalPDFをフォーム上で表示させる方法につきまして(4) | NomalPictureBoxの画像を連続保存(11) | NomalテキストボックスのValidatingイベントよりも先に発生するボタン発生イベントは何でしょう?(2) | Nomal継承元フォームで各フォームのボタン動作を検知したい(3) | NomalWindowsエクスプローラからのドラッグ&ドロップ(2) | Nomalラジオボタンの一括設定(7) | Nomalクリックイベントでexeを作成できるか(2) | Nomal作成した白黒画像をWordに貼り付けてから「図として保存」(8) | Nomalアセンブリ情報が載らない(1) | NomalRichTextBoxのテキストをpictureBOXへ(12) | Nomalc#で日付型の定義の仕方で質問があります。(2) | Nomal先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える(6) | NomalExcel Com オブジェクトの増殖(13) | Nomal二次元マップから値の取得(1) | NomalアプリでHDMIへ出す解像度を変えたい(4) | NomalDataGridViewのドロップダウンリストの表示と選択後の値を分けたい(1) | Nomal列車の時間ごとの位置情報を表示したいです。(2) | Nomal画像の中心を基点に回転(4) | NomalDataGridViewの行ヘッダーに行番号を表示した時のエラー(4) | NomalタッチキーボードでIMEを自動で切替えたい(6) | NomalVSTOによるエクセルアドインのインストーラーでのアップデート(1) | NomalMP4動画を再生する方法について(5) | NomalVB.NetでVB6.0と同じFontを指定しても同様に印刷されない(9) | NomalLabelで文字単位の背景色(7) | NomalLableのカラー色を文字変数から変更したい(5) | NomalUrlにアクセスするとダウンロードされるファイルを捕まえる(2) | Nomalタブレット等でスワイプによるスクロールを実装(2) | NomalTEXTBOXのプロパティを文字列に(7) | NomalPDFをフォーム上で表示させる方法につきまして(6) | NomalChart X軸上の描画を切り替えたい(0) | NomalRichTextBoxへのドラッグ&ドロップしたExcelファイルの扱い(3) | Nomal特定のPCだけ発生する「パディングは無効なので削除できません」のエラーの原因(6) | NomalASP.NET WebApi内でXmlReader.Create(url)がタイムアウトする(4) | NomalDatagridViewでファンクションキーを止めたい(5) | Nomal表示動作が重くなる(3) | Nomalbitmapを複数スレッドで処理したい(2) | Nomalフォーム背景のみを半透明にしたい(5) | Nomal読み出し元フォームの位置取得方法(2) | NomalLoadOptionのパラメータの意味(3) | Nomalコンストラクターに続く{}の意味(2) | Nomal1行で書くことできますか?(3) | Nomalvb.netで7zの圧縮・解凍をしたい。(2) | NomalCommandBuilderによって作られるCommandTextの内容(5) | NomalDataGridViewの特定セルにボタンを配置する方法(5) |



■記事リスト / ▼下のスレッド
■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]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35494 / 親記事)  VB.NETからcmdでpingを実行した時の結果
□投稿者/ ぱんだ 一般人(1回)-(2023/08/22(Tue) 19:38:48)
  • アイコン環境/言語:[環境:Windows11 Pro 64bit 使用言語:VB.NET(Visual Studio 2022)] 
    分類:[.NET] 

    はじめまして。
    
    最近プログラミングを始めようと思い立ち以下のサンプルを試してみたのですが、
    pingのように結果がリアルタイム?で何度も返ってくる場合のサンプルコードを
    知りたいです。
    https://dobon.net/vb/dotnet/process/standardoutput.html
    
    ipconfigなどのように結果が1回で終わるものは上記のサンプルで出来ました。
    
    Visual Studio 2022をWindows11 Pro 64bitで使用しています。
    
    お手数をおかけしますが、よろしくお願いいたします。
    

違反を報告
引用返信

▽[全レス5件(ResNo.1-5 表示)]
■35495 / ResNo.1)  Re[1]: VB.NETからcmdでpingを実行した時の結果
□投稿者/ KOZ 一般人(23回)-(2023/08/22(Tue) 21:00:42)
  • アイコン
    No35494に返信(ぱんださんの記事)
    > pingのように結果がリアルタイム?で何度も返ってくる場合のサンプルコードを
    > 知りたいです。
    
    Process.StandardOutput は StreamReader です。
    EndOfStream プロパティが True になるまで ReadLine を繰り返してください。
    
    Using p As New Process
        p.StartInfo.FileName = Environment.GetEnvironmentVariable("ComSpec")
        p.StartInfo.UseShellExecute = False
        p.StartInfo.RedirectStandardOutput = True
        p.StartInfo.RedirectStandardInput = False
        p.StartInfo.CreateNoWindow = True
        p.StartInfo.Arguments = "/c ping 127.0.0.1"
        p.Start()
        Dim reader = p.StandardOutput
        Do Until reader.EndOfStream
            Dim buffer = reader.ReadLine()
            Console.WriteLine(buffer)
        Loop
        p.WaitForExit()
    End Using
    Console.WriteLine("何かキーを押すと終了します。")
    Console.ReadKey()
    

違反を報告
引用返信
■35496 / ResNo.2)  Re[2]: VB.NETからcmdでpingを実行した時の結果
□投稿者/ ぱんだ 一般人(2回)-(2023/08/22(Tue) 23:54:44)
  • アイコン
    早速の返信ありがとうございます。
    おかげさまで以下のコードで実現できて助かりました。
    これから少しづつ学んでいこうと思います。
    ありがとうございました。
    
            Using p As New Process
                p.StartInfo.FileName = Environment.GetEnvironmentVariable("ComSpec")
                p.StartInfo.UseShellExecute = False
                p.StartInfo.RedirectStandardOutput = True
                p.StartInfo.RedirectStandardInput = False
                p.StartInfo.CreateNoWindow = True
                p.StartInfo.Arguments = "/c ping 127.0.0.1"
                p.Start()
                Dim reader = p.StandardOutput
                Do Until reader.EndOfStream
                    Dim buffer = reader.ReadLine()
                    '以下3行を追加
                    Debug.Print(buffer)
                    TextBox1.Text = TextBox1.Text & vbCrLf & buffer
                    Me.Refresh()
                Loop
                p.WaitForExit()
            End Using

違反を報告
引用返信
■35497 / ResNo.3)  Re[2]: VB.NETからcmdでpingを実行した時の結果
□投稿者/ ぱんだ 一般人(3回)-(2023/08/23(Wed) 00:12:12)
  • アイコン
    KOZさん
    
    度々すみません。
    以下のコードと添付写真の通り作成してみたのですが、
    例えば添付写真のように途中でキャンセルする方法はありますか?
    実行中は他のボタンも押せなくなってしまいます。
    何度も申し訳ありませんが、可能でしたらサンプルコードを教えて
    いただけましたら幸いです。
    何卒よろしくお願いいたします。
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'Process.StandardOutput は StreamReader です。
            'EndOfStream プロパティが True になるまで ReadLine を繰り返してください。
    
            Using p As New Process
                p.StartInfo.FileName = Environment.GetEnvironmentVariable("ComSpec")
                p.StartInfo.UseShellExecute = False
                p.StartInfo.RedirectStandardOutput = True
                p.StartInfo.RedirectStandardInput = False
                p.StartInfo.CreateNoWindow = True
                'p.StartInfo.Arguments = "/c ping 127.0.0.1"
                p.StartInfo.Arguments = "/c " & TextBox2.Text
                p.Start()
                Dim reader = p.StandardOutput
                Do Until reader.EndOfStream
                    Dim buffer = reader.ReadLine()
                    'Console.WriteLine(buffer)
                    Debug.Print(buffer)
                    TextBox1.Text = TextBox1.Text & vbCrLf & buffer
                    Me.Refresh()
                Loop
                p.WaitForExit()
            End Using
            'Console.WriteLine("何かキーを押すと終了します。")
            'Console.ReadKey()
        End Sub

639×389 => 250×152
イメージ
2023-08-23.png
/11KB
違反を報告
引用返信
■35498 / ResNo.4)  Re[3]: VB.NETからcmdでpingを実行した時の結果
□投稿者/ KOZ 一般人(24回)-(2023/08/23(Wed) 05:54:27)
  • アイコン
    2023/08/23(Wed) 05:57:00 編集(投稿者)
    
    ■No35497に返信(ぱんださんの記事)
    
    CTRL+C を送ってキャンセルでいいんですかね?
    
    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        Private cmdProcess As Process
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If cmdProcess IsNot Nothing Then Return
            TextBox1.Clear()
            cmdProcess = New Process
            cmdProcess.StartInfo.FileName = Environment.GetEnvironmentVariable("ComSpec")
            cmdProcess.StartInfo.UseShellExecute = False
            cmdProcess.StartInfo.RedirectStandardOutput = True
            cmdProcess.StartInfo.RedirectStandardInput = False
            cmdProcess.StartInfo.CreateNoWindow = True
            cmdProcess.StartInfo.Arguments = "/c " & TextBox2.Text
            cmdProcess.Start()
            Task.Run(AddressOf ReadTask)
            Button1.Enabled = False
            Button2.Enabled = True
        End Sub
    
        Private Sub ReadTask()
            Dim reader = cmdProcess.StandardOutput
            Do Until reader.EndOfStream
                Dim buffer = reader.ReadLine()
                Invoke(Sub()
                           TextBox1.AppendText(vbCrLf & buffer)
                           Refresh()
                       End Sub)
            Loop
            cmdProcess.WaitForExit()
            cmdProcess.Dispose()
            cmdProcess = Nothing
            Invoke(Sub()
                       Button1.Enabled = True
                       Button2.Enabled = False
                   End Sub)
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            If AttachConsole(cmdProcess.Id) Then
                SetConsoleCtrlHandler(IntPtr.Zero, True)
                GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)
                cmdProcess.WaitForExit()
                SetConsoleCtrlHandler(IntPtr.Zero, False)
                FreeConsole()
            End If
        End Sub
    
        Private Const CTRL_C_EVENT = 0
        Private Const CTRL_BREAK_EVENT = 1
    
        <DllImport("Kernel32")>
        Private Shared Sub GenerateConsoleCtrlEvent(dwCtrlEvent As Integer, dwProcessGroupId As Integer)
        End Sub
    
        <DllImport("Kernel32")>
        Private Shared Function AttachConsole(dwProcessId As Integer) As Boolean
        End Function
    
        <DllImport("Kernel32")>
        Private Shared Function SetConsoleCtrlHandler(HandlerRoutine As IntPtr, add As Boolean) As Boolean
        End Function
    
        <DllImport("Kernel32")>
        Private Shared Function FreeConsole() As Boolean
        End Function
    
    End Class
    

違反を報告
引用返信
■35501 / ResNo.5)  Re[4]: VB.NETからcmdでpingを実行した時の結果
□投稿者/ ぱんだ 一般人(1回)-(2023/08/23(Wed) 21:05:09)
  • アイコン
    2023/08/23(Wed) 21:08:45 編集(投稿者)
    
    KOZさん
    
    早速ありがとうございます。
    
    複雑な処理が必要なんですね!
    サンプルコードを元に勉強していきたいと思います。
    本当にどうもありがとうございました。

違反を報告
引用返信

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



■記事リスト / ▼下のスレッド / ▲上のスレッド
■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]



■記事リスト / ▲上のスレッド
■35487 / 親記事)  vb.netでのExcelファイルそうさ
□投稿者/ 独学学生 一般人(1回)-(2023/08/18(Fri) 19:37:57)
  • アイコン環境/言語:[Windows10] 
    分類:[.NET] 

    vb.netで下記プログラムを実行するとバックグラウンドプロセスにタスクが必ず残ってしまいます。
    フォームアプリを終了するとプロセスが消えるのですがバックグラウンドプロセスに残らない方法はありますか?

    private sub btn作成_Click(sender as object,e as eventargs)handles btn作成.click
    If txtpath.text =“” then
    exit sub
    end if

    btn作成.enabled =false

    dim str as string =“”
    dim strcount =0

    dim ex as new
    Microsoft.office.interop.Excel.application
    dim sh as Microsoft.office.interop.Excel.worksheet
    dim wb as Microsoft.office.interop.Excel.workbook
    dim range as Microsoft.office.interop.Excel.range

    For rw as integer =0 to dgv.rowcount -1
    if dgv.rows(rw).cells(“選択”).value=1 then
    str=dgv.row(rw).cells(“品名”).value & vbcrlf
    str &= dgv.row(rw).cells(“数量”).value & vbcrlf
    str &= dgv.row(rw).cells(“単位”).value & vbcrlf

    if strcount =0 then
    wb=ex.workbooks.open (txtpath.text)
    sh=ex.worksheets(“発注”)

    dim strarry() as string =str.split({environment.newline},stringsplitoptions.none)
    dim arrycount =0

    range = sh.range(“B” & 5 + strcount & “:I” & 5 + strcount)

    for col as integer =1 to range.columns.count
    range.cells(1,col).value =strarry(arrycount)
    system.runtime.InteropService.Marshal.release comobject(range.cells(1,col))
    arrycount =arrycount + 1
    next

    strcount =strcount + 1

    end if
    next

    wb.save()
    we.close(false)
    ex.quit()

    system.runtime.InteropService.Marshal.release comobject(range)
    system.runtime.InteropService.Marshal.release comobject(sh)
    system.runtime.InteropService.Marshal.release comobject(wb)
    system.runtime.InteropService.Marshal.release comobject(ex)

    Range=nothing
    Sh=nothing
    Wb=nothing
    Ex=nothing

    gc .Collect()
    gc.waitforpendingfinalizers()

    btn作成.enabled =true

    Msgbox(“作業完了”)
    end sub

違反を報告
引用返信

▽[全レス2件(ResNo.1-2 表示)]
■35488 / ResNo.1)  Re[1]: vb.netでのExcelファイルそうさ
□投稿者/ Hongliang 大御所(644回)-(2023/08/18(Fri) 20:11:07)
  • アイコン> wb=ex.workbooks.open (txtpath.text)
    Workbooksオブジェクトが解放漏れ
    > for col as integer =1 to range.columns.count
    columnsであるRangeオブジェクトが解放漏れ
    > range.cells(1,col).value =strarry(arrycount)
    cells(,)が返すRangeオブジェクトが解放漏れ
    他にもあるかもしれませんがとりあえず目についただけ。
    hoge.fuga.piyoのようにピリオドが1文に2個存在してたら漏れてると考えたほうがいいです。

    > system.runtime.InteropService.Marshal.releasecomobject(range.cells(1,col))
    意味がないです。
    上と合わせてrange.cells(,)を2回取って1回分だけ解放している計算です。
    取得したオブジェクトは変数に確保しておき、それに対してReleaseComObjectする必要があります。

    まともにReleaseComObjectを考えると正直切りがないんで、Excel操作だけを別のexeとして作成し、そっちに全部任せちゃうってのもありかもしれませんね。
    DataGridのデータを読み取って、いったんファイルに書き込んで、操作用exeはファイルから読み込んでExcelをいじる、みたいな。

    あとは、単純にセルの中身をいじるだけならClosedXmlみたいなライブラリを使用するとか。
違反を報告
引用返信
■35489 / ResNo.2)  Re[1]: vb.netでのExcelファイルそうさ
□投稿者/ KOZ 一般人(22回)-(2023/08/18(Fri) 20:16:52)
  • アイコンNetOffice Framework を使ったらどうでしょう?
    https://netoffice.io/

違反を報告
引用返信

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






Mode/  Pass/


- Child Tree -