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

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

記事リスト ( )内の数字はレス数
Nomalフォントに登録されていない文字の検出(1) | Nomaloledbでdatatableを取得するときにエラーになる(1) | Nomal作成した白黒画像をWordに貼り付けてから「図として保存」(8) | NomalVB.NetでVB6.0と同じFontを指定しても同様に印刷されない(9) | NomalDataGridViewの複数行選択で歯抜け選択を無効にしたい(2) | Nomal証券会社へのログイン(1) | 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アセンブリ情報が載らない(1) | Nomal先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える(6) | Nomalc#で日付型の定義の仕方で質問があります。(2) | NomalExcel Com オブジェクトの増殖(13) | Nomal二次元マップから値の取得(1) | NomalアプリでHDMIへ出す解像度を変えたい(4) | Nomal列車の時間ごとの位置情報を表示したいです。(2) | Nomal画像の中心を基点に回転(4) | NomalDataGridViewのドロップダウンリストの表示と選択後の値を分けたい(1) | 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) |



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



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



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



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35479 / 親記事)  キーボード+バーコードでキーボード入力を無効にしたい
□投稿者/ たろう 一般人(4回)-(2023/08/04(Fri) 10:03:12)
  • アイコン環境/言語:[windows11/Visual Studio 2022/C#] 
    分類:[.NET] 

    バーコードを利用したシステムで、バーコードから情報を読みこんでいるときにキーボードを触るとバーコードから読み込んだ文字列の間に文字が入ってしまいます。

    バーコードはキーボードエミュレーションのため上記は仕方がないのですが、なにか対策をしなければいけません。

    バーコード入力時は特定のテキストボックスにフォーカスがあるので、その時だけキーボードを無効にしてバーコードのみを有効にするような事ができれば良いのですが・・・。

    なにか手だてはないでしょうか。


違反を報告
引用返信

▽[全レス6件(ResNo.2-6 表示)]
■35481 / ResNo.2)  Re[2]: キーボード+バーコードでキーボード入力を無効にしたい
□投稿者/ たろう 一般人(5回)-(2023/08/04(Fri) 13:48:31)
  • アイコンNo35480に返信(魔界の仮面弁士さんの記事)
    > そういった恐れのある環境では、
    > HID エミュレート型ではなく、
    > Serial 型の製品が採用されます。

    そうですよね・・・。
    いえ、まったくおっしゃる通りです。
    このバーコードもキーボードエミュレーションではないモードを持っているようですが
    元請けからできるだけいまの仕組みを変えたくないと言われている状況で何か方法がないか検討しておりました。


    > なお、複数のキーボードが入力されているケースなどでは、
    > SharpDX.RawInput を使うことで、どちらのキーボードの
    > キーが押されたのかを拾うことはできていますが、

    なるほど、キーボードが2つある場合は判断ができるのですね。
    バーコードでも可能かどうかは分かりませんが、参考にさせていただきます。


違反を報告
引用返信
■35483 / ResNo.3)  Re[1]: キーボード+バーコードでキーボード入力を無効にしたい
□投稿者/ とくま 一般人(3回)-(2023/08/04(Fri) 20:37:31)
  • アイコンNo35479に返信(たろうさんの記事)
    ざっくり検索して内容検証してないですが、ウィンドウズメッセージを解析する方向なら
    RAWINPUTHEADERの hDeviceが違うんじゃないかみたいな話とか
    https://teratail.com/questions/215793
    C++の分野だとか、デバイスドライバを自分で作るような話という方向の話はあるようです。

    本音は、
    バーコードリーダーが壊れたときとか、キーボード入力での代替作業が必要となるトラブルは
    必ず起こるので、そのような仕様自体、避けますけどね。現場に直接言われたなら、
    『USB端子をPCの前面に配置しますので、キーボード入力を避けたい場合は、物理的に抜く
    運用でどうでしょうか?』って言っちゃうw趣味で開発するならまだしも、費用対効果を考える
    システムでやる内容ではないようにも思います。
違反を報告
引用返信
■35484 / ResNo.4)  Re[3]: キーボード+バーコードでキーボード入力を無効にしたい
□投稿者/ kiku 一般人(1回)-(2023/08/07(Mon) 19:01:16)
  • アイコンNo35481に返信(たろうさんの記事)
    > ■No35480に返信(魔界の仮面弁士さんの記事)
    >>そういった恐れのある環境では、
    >>HID エミュレート型ではなく、
    >>Serial 型の製品が採用されます。
    >
    > そうですよね・・・。
    > いえ、まったくおっしゃる通りです。
    > このバーコードもキーボードエミュレーションではないモードを持っているようですが
    > 元請けからできるだけいまの仕組みを変えたくないと言われている状況で何か方法がないか検討しておりました。
    >
    >
    >>なお、複数のキーボードが入力されているケースなどでは、
    >>SharpDX.RawInput を使うことで、どちらのキーボードの
    >>キーが押されたのかを拾うことはできていますが、
    >
    > なるほど、キーボードが2つある場合は判断ができるのですね。
    > バーコードでも可能かどうかは分かりませんが、参考にさせていただきます。

    魔界の仮面弁士さんのコメントが妥当と思います。

    もし、入力文字列の長さが固定であれば、
    文字列長で判定し、キーボードからの入力があった場合
    文字列長が想定より長くなることで、
    判定できるのではと思いました。

違反を報告
引用返信
■35485 / ResNo.5)  Re[2]: キーボード+バーコードでキーボード入力を無効にしたい
□投稿者/ たろう 一般人(6回)-(2023/08/08(Tue) 10:48:27)
  • アイコンNo35483に返信(とくまさんの記事)

    デバイスドライバを作ったりということはさすがに難易度が高いので難しいですね…

    とりあえず、「キーボードを触らないで」とお願いする方向になるかもです。
    (「触ってねぇよ。システムの不具合だろう」って言われそうな気もしますが)

違反を報告
引用返信
■35486 / ResNo.6)  Re[4]: キーボード+バーコードでキーボード入力を無効にしたい
□投稿者/ たろう 一般人(7回)-(2023/08/08(Tue) 10:51:27)
  • アイコンNo35484に返信(kikuさんの記事)
    > 魔界の仮面弁士さんのコメントが妥当と思います。

    そうですね…
    文字列は固定長とは限らず、チェックデジットもないというか、フリーフォーマットのようで、用紙ごとに何が書いてあるかは分からないそうで、なかなか難しいです。

    キーボード入力だけはじくというのは簡単ではなさそうなので、本件はこれにて終了といたします。


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

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



■記事リスト / ▲上のスレッド
■35466 / 親記事)  VB2022でクリスタルレポートが開けない
□投稿者/ zingbay 一般人(1回)-(2023/07/08(Sat) 22:02:52)
  • アイコン環境/言語:[Win10/Win11 .net4.8] 
    分類:[その他] 

    VB2012+バンドル版のクリスタルレポートで動かしているシステムがあり、それをマイグレーションしようとしています。
    マイグレ先はVB2022+同じくバンドル版のクリスタルレポートです。
    CRforVS6413SP33_0-80007712.EXEをSAPのサイトよりダウンロードし、インストールしました。
    
    Visual Studioでvb2021のプロジェクトを開き、含まれているレポート(.rptファイル)をクリックして開こうとしたところ、「クラスが登録されていません」が表示され、開く事ができません。
    
    対応方法が分からず、こちらへポストさせて頂きました。
    SAP公式の掲示板で同じような事象が無いかを調べたのですが、見つける事ができませんでした。
    
    何か、調べる手立てや対応方法をご教示頂けませんか?
    
    
    

違反を報告
引用返信

▽[全レス2件(ResNo.1-2 表示)]
■35473 / ResNo.1)  Re[1]: VB2022でクリスタルレポートが開けない
□投稿者/ とくま 一般人(1回)-(2023/07/11(Tue) 23:13:38)
  • アイコン2023/08/04(Fri) 20:19:32 編集(投稿者)

    No35466に返信(zingbayさんの記事)
    Crystal Reportsは、名前は同じですが、途中で開発元会社が変わっており、バージョンの違いで
    運用方法なども違いが出てきます。
    https://ja.wikipedia.org/wiki/Crystal_Reports
    そのうち、バンドル版と呼ばれるのは、Visusl Studioに同梱されてインストールされていた
    VS2008までのものを指すと思います。
    https://userapps.support.sap.com/sap/support/knowledge/ja/1514084
    >VB2012+バンドル版のクリスタルレポート
    →存在しません
    >VB2022+同じくバンドル版のクリスタルレポート
    →存在しません
    >SAPのサイトよりダウンロードし、
    →「SAP Crystal Reports」と呼びますが、機能的に呼ぶならプラグイン版です。バンドル版とは別物になります。

    ただ、ここで落とし穴は、Visusl Studioが下位互換で、ターゲットフレームワークを
    変えられることです。PCにインストールされているのはVS2015で、とあるプロジェクトは
    VS2008と同じビルドという場合があります。プロジェクトのプロパティ画面で「対象のフレームワーク」
    となっている部分に .NET Framework のバージョンの何が設定されているかになります。
    https://learn.microsoft.com/ja-jp/visualstudio/ide/visual-studio-multi-targeting-overview?view=vs-2022
    .NET FrameworkとVisusl Studioの対応表は以下。
    https://qiita.com/nskydiving/items/3af8bab5a0a63ccb9893

    ここまでで、マイグレーション元の
    >VB2012+バンドル版のクリスタルレポート
    で、正確な@ビルド時の.NET Framework のバージョンとACrystal Reportsのバージョンを調べてください。
    https://wiki.scn.sap.com/wiki/display/BOBJ/Which+Crystal+Reports+assembly+versions+are+supported+in+which+versions+of+Visual+Studio+.NET
    https://wiki.scn.sap.com/wiki/display/BOBJ/SAP+Crystal+Products+-+End+of+Mainstream+Maintenance+Dates

違反を報告
引用返信
■35482 / ResNo.2)  Re[1]: VB2022でクリスタルレポートが開けない
□投稿者/ とくま 一般人(2回)-(2023/08/04(Fri) 20:21:36)
  • アイコンNo35466に返信(zingbayさんの記事)
    反応ないので、内容は当たり前のことかもしれないけど、備忘録としてまとめ。

    バンドル版というのが本当であれば、プロジェクトはVB2012だけど、ソースコード及びレポートファイルはVB2008で
    実質、『VB2008+バンドル版クリレポ』→『VB2022+プラグイン版最新クリレポ』のマイグレーションとかなるわけです。

    私は、バンドル版→プラグイン版の時点で、配布の手間が多かったため、見送りました。まず、ランタイムが全く別で
    ある点。そしてマージモジュールを含むインストーラを用意しないと正常に稼働しないという情報があったから
    です。Win11で.NetFramework3.5以下が廃止に向けて分離されてる臭いですが、2,3年はまだ延命できるでしょう。
    そうすればシステム全体を見直す余地も出てきます。ユーザ数が多いと、こんな判断も必要かもしれません。

    さて、
    VBもクリレポも、基本的にはバージョン違いを同じ端末にインストール可能だと思われますが、こういう
    マイグレーション時は別のPCを用意したほうが良いです。
    >Visual Studioでvb2021のプロジェクトを開き、含まれているレポート(.rptファイル)をクリックして開こうとしたところ
    いきなりこんなことせず、まずは『VB2022+プラグイン版最新クリレポ』で新規レポートを作成して正常稼働できる
    確認が必要です。プラグイン版クリレポは、開発環境にランタイムをインストールすると不具合が起きるという
    情報もあり、開発PCとテストPCも別のほうが良いでしょう。
    https://trapemiya.hatenablog.com/entry/2020/02/19/021446

    『VB2022+プラグイン版最新クリレポ』が動かないなら、公式サポートを受けるのが早いと思います。
    で、正常稼働ができることを確認してから、レポートの自動アップグレードが可能かテストします。
    アップグレードが走らなければ、おそらくそのまま移行はできないと思われます。
    そうなると、旧開発環境でレポートを開き、設定を見ながら、新規レポートで再作成するしかないと
    思われます。
違反を報告
引用返信

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






Mode/  Pass/


- Child Tree -