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

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

記事リスト ( )内の数字はレス数
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) | NomalASP.NET WebApi内でXmlReader.Create(url)がタイムアウトする(4) | NomalDatagridViewでファンクションキーを止めたい(5) | Nomal表示動作が重くなる(3) |



■記事リスト / ▼下のスレッド
■35292 / 親記事)  クリックイベントでexeを作成できるか
□投稿者/ TMK 一般人(1回)-(2022/12/17(Sat) 12:07:39)
  • アイコン環境/言語:[C# (VS2008)] 
    分類:[.NET] 

    皆さま こんにちは

    ユーザーフォームのクリックイベントでexeの作成は可能なのでしょうか

    配布用exeを作ろうと思っています。
    exeの目的は、共通のファイル等の操作でヒューマンエラーが起こらないよう、
    ワンクリックで自動的に処理したいのです。

    ただ、動作させる環境を限定させたいので、多少のパラメータをexeに渡す必要があります。
    ユーザーフォームでパラメータを選択し、クリックイベントでパラメータを含んだexeを作成する(exeで参照)、
    そんな感じのプロジェクトを作成したいと思っています。
    パラメータの条件を満たさない環境では何もせずにreturnさせたいのです。

    batファイルでexeを作るようにした方が良いのかなとも思うのですが、
    使用者のことを考えるとユーザーフォームでボタンクリックの方が親切かなと思っています。

    しかし、C#では無理があることなのか私の検索方法が悪いのか、
    あまりヒントとなるネタを見つけることができません。

    ということで、最初に戻るのですが、ユーザーフォームのクリックイベントでexeを作成することは可能なのでしょうか。
違反を報告
引用返信

▽[全レス2件(ResNo.1-2 表示)]
■35293 / ResNo.1)  Re[1]: クリックイベントでexeを作成できるか
□投稿者/ KOZ 一般人(15回)-(2022/12/17(Sat) 12:55:31)
  • アイコンNo35292に返信(TMKさんの記事)
    > ユーザーフォームのクリックイベントでexeの作成は可能なのでしょうか

    ソースを出力してコンパイルすればいいのでは。
    「OSに標準付属のC#/VBコンパイラーでソースコードをコンパイルするには?」
    https://atmarkit.itmedia.co.jp/ait/articles/1504/15/news019.html

    パラメタを外部ファイルから読み込むようにした exe ファイルを配布し、
    外部ファイルを編集するのが一般的かなと思います。
違反を報告
引用返信
■35294 / ResNo.2)  Re[1]: クリックイベントでexeを作成できるか
□投稿者/ Hongliang 大御所(636回)-(2022/12/18(Sun) 19:42:04)
  • アイコン「exeを作成する」というとソースコードをコンパイルして実行ファイルを作成することを想像するのですが、
    ひょっとしてなさりたいことは「引数を付けて.exeを起動したい」でしょうか。
    それならば以下のページなどがありますが。
    https://dobon.net/vb/dotnet/process/shell.html
違反を報告
引用返信

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



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35278 / 親記事)  アセンブリ情報が載らない
□投稿者/ Rolulu 一般人(1回)-(2022/12/08(Thu) 18:16:40)
  • アイコン環境/言語:[VB.NET] 
    分類:[.NET] 

    はじめまして。
    VS2019でVBアプリを作っています。

    その中でMyProjectのアプリケーションにあるアセンブリ情報を入力したのですが、ビルドやデバックした実行ファイルには反映されていませんでした。
    実行ファイルのプロパティの詳細に載っているのは、種類がアプリケーションとサイズと更新日だけでした。

    アセンブリ情報がなぜ反映されないのかわからず質問させていただきました。
違反を報告
引用返信

▽[全レス1件(ResNo.1-1 表示)]
■35289 / ResNo.1)  Re[1]: アセンブリ情報が載らない
□投稿者/ shu 大御所(500回)-(2022/12/16(Fri) 16:36:34)
  • アイコンNo35278に返信(Roluluさんの記事)

    正しいと思われる操作だけでなく
    行われた操作をプロジェクト作成から
    その状態を確認するまでどのように行ったのかを
    記載された方がよいと思います。
違反を報告
引用返信

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



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35259 / 親記事)  先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える
□投稿者/ ま〜 一般人(23回)-(2022/12/01(Thu) 13:34:12)
  • アイコン環境/言語:[Windows10 VS20222] 
    分類:[.NET] 

    いつもありがとうございます。またハマってます。

    例)" 1 2345"の文字列
       ↑スペース
      
    テキストファイルの内容に先頭にスペースがあるファイルを読み込んでRichTextBoxへ書き出すと先頭のスペース全部が削除されます
    "1 2345こんな感じになります。"
    間にある(1と2間)スースは消えません。
    何がダメなのか分からない状況です。

    Dim sr As Microsoft.VisualBasic.FileIO.TextFieldParser = New Microsoft.VisualBasic.FileIO.TextFieldParser (DataPath & "文字.TXT", System.Text.Encoding.GetEncoding("shift_jis"))

    '内容は区切り文字形式
    sr.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited

    'デリミタはカンマ
    sr.SetDelimiters(",")

    Dim Row As String() '= sr.ReadFields
    '一行目を読み込
    Row = sr.ReadFields()
    RichTextBox1.Text = Row(0)
    Console.WriteLine(Row(0))

    上記の様にやってます。アドバイスお願いします。
違反を報告
引用返信

▽[全レス6件(ResNo.2-6 表示)]
■35261 / ResNo.2)  Re[1]: 先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える
□投稿者/ KOZ 一般人(7回)-(2022/12/01(Thu) 14:19:47)
  • アイコンNo35259に返信(ま〜さんの記事)
    > テキストファイルの内容に先頭にスペースがあるファイルを読み込んでRichTextBoxへ書き出すと先頭のスペース全部が削除されます

    こういうふうに書くということは、どこでスペースが削除されているのか、調べていないということですか?
    せめて原因がどこにあるか突き止めてから書き込みましょう。
    RichTextBox は関係ないですよね?

    「TextFieldParser.TrimWhiteSpace プロパティ」
    https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.fileio.textfieldparser.trimwhitespace?view=netframework-4.8
    を False にしてください。

違反を報告
引用返信
■35263 / ResNo.3)  Re[1]: 先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える
□投稿者/ 魔界の仮面弁士 大御所(1496回)-(2022/12/01(Thu) 14:39:24)
  • アイコンNo35259に返信(ま〜さんの記事)
    > テキストファイルの内容に先頭にスペースがあるファイルを読み込んで
    > RichTextBoxへ書き出すと先頭のスペース全部が削除されます
    どこまで調査されましたか?

    その事象は、RichTextBox の問題なのでしょうか。
    テキストファイル読み取りの問題なのでしょうか。


    > RichTextBox1.Text = Row(0)
    この時、Row(0) の先頭に空白が含まれているかどうかを確認済みでしょうか?


    Row(0) の先頭に空白が既に含まれていたのであれば、
    「先頭に空白があるファイル」の読み込みは成功していて
    「RichTextBoxへ書き出すとスペースが削除される」という状況といえるでしょう。

    その場合、質問時に TextFieldParser に関するくだりを述べる必要はなく、
    単純に「RichTextBox1.Text = " 1 2345"」に関する動作を示すだけで良いはず。


    一方、Row(0) の時点で先頭空白が失われてしまう状況なのであれば、
    RichTextBox は一切関係ないことになります。その場合はファイルの
    読み込み手順によるもの(TextFieldParser を使うことの是非)でないかを調べたり
    ファイル内容に問題が無いか(空白に見えるが、実は別の不可視文字だったとか)を
    調べることになりますよね。場合によっては、
     RichTextBox1.LoadFile(DataPath & "文字.TXT", RichTextBoxStreamType.PlainText)
    の結果と比較してみても良いかもしれません。


    > 上記の様にやってます。アドバイスお願いします。
    結論から言えば、TextFieldParser が原因です。
    このクラスは先頭末尾空白を自動的に削除しますし、
    改行のみの行(いわゆる空行)も無視する仕様です。

    先頭末尾空白については TrimWhiteSpace プロパティで抑制できますが
    空行無視は回避策がなかったはずなので、要件次第では
    TextFieldParser 以外の選択肢を検討した方が良いかと思います。
違反を報告
引用返信
■35264 / ResNo.4)  Re[2]: 先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える
□投稿者/ ま〜 一般人(26回)-(2022/12/01(Thu) 14:55:09)
  • アイコンKOZさん魔界さんありがとうございます

    ご指摘の様にRichTextBoxは関係無くファイルから変数に読み込んだ段階で消えています。
    仕様なんですね。なんか私にはハードルが高くなってきました。

違反を報告
引用返信
■35265 / ResNo.5)  Re[3]: 先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える
□投稿者/ KOZ 一般人(8回)-(2022/12/01(Thu) 16:43:39)
  • アイコンNo35264に返信(ま〜さんの記事)
    > KOZさん魔界さんありがとうございます

    「魔界さん」ではなく、「弁士さん」と呼びましょう。
    # 遠い昔、本人がおっしゃってたので(^_^;)

    > ご指摘の様にRichTextBoxは関係無くファイルから変数に読み込んだ段階で消えています。
    > 仕様なんですね。なんか私にはハードルが高くなってきました。

    弁士さんが書いてらっしゃいますが要件次第です。
    項目に改行がない、空行を無視して良いなら TextFieldParser で充分かと。

違反を報告
引用返信
■35269 / ResNo.6)  Re[4]: 先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える
□投稿者/ ま〜 一般人(27回)-(2022/12/05(Mon) 15:33:41)
  • アイコン出来ました。
    ありがとうございます。
解決み!
違反を報告
引用返信

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



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35266 / 親記事)  c#で日付型の定義の仕方で質問があります。
□投稿者/ sun 一般人(1回)-(2022/12/02(Fri) 15:58:32)
  • アイコン環境/言語:[C#] 
    分類:[.NET] 

    はじめまして。
    C#でプログラムを組むことになったのですが、よくわからない定義の仕方がありまして、ググったのですが分かりませんでした。
    どなたかおしえていただけないでしょうか?

    下記の?の意味が分からなくて。
     public decimal? id;
     public DateTime? edate;



違反を報告
引用返信

▽[全レス2件(ResNo.1-2 表示)]
■35267 / ResNo.1)  Re[1]: c#で日付型の定義の仕方で質問があります。
□投稿者/ 魔界の仮面弁士 大御所(1497回)-(2022/12/02(Fri) 17:03:40)
  • アイコン2022/12/02(Fri) 23:51:36 編集(投稿者)

    No35266に返信(sunさんの記事)
    > 下記の?の意味が分からなくて。
    >  public decimal? id;
    >  public DateTime? edate;
    これらは
     public Nullable<decimal> id;
     public Nullable<DateTime> edate;
    の省略表記です。
    こうしたデータ型は「null 許容値型」と呼ばれます。


    string や Form などは「クラス」です。
    クラスは「参照型」であり、default 値は null です。

    decimal や int や bool や DateTime は「構造体」です。
    構造体は「値型」であり、default 値はゼロです。

    そして構造体には null をセットできません。

    string a = default(string); // string a = null; と同義
    int b = default(int); // int b = 0; と同義
    bool c = default(bool); // bool c = false; と同義

    しかし Nullable<T> すなわち T? 型にすると、null が許容されます。

    int? x = null; // 0 とは異なる
    int? y = 123;
    int? z = x + y;

    たとえば bool 型は、true と false の二値のみの型ですが、
    bool? 型にすれば、true と false と null の三値を持てることになります。


    > C#でプログラムを組むことになったのですが、
    「C#」ではなく、
    「C#」と書いた方が良いでしょう。


    日本工業規格 JIS X 3015 "プログラミング言語C#"
    →序文 6 [頭字語及び略語]
    》 箇条6は,参考であって,規定ではない。
    (中略)
    》 C#は,“しーしゃーぷ”と発音する。
    》 C#は,LATIN CAPITAL LETTER C (U+0043)の次にNUMBER SIGN # (U+0023)を書く。

    ECMA-334 "C# Language Specification"
    ISO/IEC 23270:2006 "Information technology -- Programming languages -- C#"
    →Introduction 6. [Acronyms and abbreviations]
    》 The name C# is pronounced “C Sharp”.
    》 The name C# is written as the LATIN CAPITAL LETTER C (U+0043) followed by the NUMBER SIGN # (U+0023).
違反を報告
引用返信
■35268 / ResNo.2)  Re[2]: c#で日付型の定義の仕方で質問があります。
□投稿者/ sun 一般人(2回)-(2022/12/02(Fri) 20:17:34)
  • アイコンこういう書き方があるの初めて知りました。

    どういう時に使用すると有益なのか、これからいろいろと書いてみて経験していきたいと思います。

    C#も記載の仕方気をつけます。

    ありがとうございました。

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

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



■記事リスト / ▲上のスレッド
■35241 / 親記事)  Excel Com オブジェクトの増殖
□投稿者/ たこ 一般人(15回)-(2022/11/27(Sun) 04:14:52)
  • アイコン環境/言語:[[Windows10 VB.NET .NET Framework 4.7.2 VS2019]] 
    分類:[.NET] 

    環境追記
    [Office 365 Excel バージョン2210]
    [Microsoft Excel 16.0 Object Library]


    いつもお世話になっております。

    今回Excelの既存データをまとめようと思いまして、
    VB.NETのExcel Comオブジェクトを使用して2枚のExcelを開いて処理しています。

    Excelの処理部分はクラスにまとめ処理していますが、タスクマネージャーで見ると閉じたはずのExcelが残っています。
    いろいろやってみましたが解決できず、お知恵をお借りしたいと投稿致します。


    <参考にしたサイト>
    https://hironimo.com/prog/vbnet/vb-net-excel/
    https://oreno-it2.info/archives/1043
    http://vbnettips.blog.shinobi.jp/file-folder/excel%20%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%93%8D%E4%BD%9C%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%EF%BC%88microsof
    http://hanatyan.sakura.ne.jp/vb2005/vb2013excel01.htm
    http://up-up-everyday.cocolog-nifty.com/wanco_programming/2015/07/vbnetexcel-81a4.html


    ExcelExクラス(抜粋)
    ----------------------------------------------------------------------------------------------------
      'Excel のアプリケーション参照用オブジェクト
      Friend xlsApplication As Excel.Application = Nothing
      'Excel の Workbooks 参照用オブジェクト (Workbook の Collection)
      Friend xlsWorkbooks As Excel.Workbooks = Nothing
      'Excel の Workbooks 内の1個の Workbook 参照用オブジェクト
      Friend xlsWorkbook As Excel.Workbook = Nothing
      'Excel の Workbook 内の Worksheets 参照用オブジェクト (Worksheet の Collection)
      Friend xlsWorkSheets As Excel.Sheets = Nothing
      'Excel の Sheets 内の1個の Worksheet 参照用オブジェクト
      Friend xlsWorkSheet As Excel.Worksheet = Nothing
      'Excel の Sheet 内の1個のセル Range 参照用オブジェクト
      Friend xlsRange As Excel.Range = Nothing

      Private _WorkBook As String = Nothing
      Private _WorkBookIsNew As Boolean = Nothing
      Public Property WorkBook As String
        Set(value As String)
          _WorkBook = value
          Select Case _WorkBook
            Case ""
              WorkBook_Open()
              _WorkBookIsNew = True
            Case "Close"
              _frgClose = True
              WorkBook_Close()
            Case "Save"
              xlsWorkbook.Save()
            Case "SaveAfterClose", "CloseBeforeSave"
              xlsWorkbook.Save()
              _frgClose = True
              WorkBook_Close()
            Case Else
              WorkBook_Open(_WorkBook)
              _WorkBookIsNew = False
          End Select
        End Set
        Get
          Return _WorkBook
        End Get
      End Property

      Private Sub WorkBook_Open(Optional ByVal strFileName As String = Nothing)
        'Excel アプリケーション起動
        xlsApplication = New Excel.Application
        'Excel の Workbooks 取得
        xlsWorkbooks = xlsApplication.Workbooks
        'Excel非表示
        xlsApplication.Visible = False
        xlsApplication.DisplayAlerts = False
        If IsNothing(strFileName) Then
          '新規 Excel ファイルを開く
          xlsWorkbook = xlsWorkbooks.Add()
        Else
          '既存 Excel ファイルを開く
          xlsWorkbook = xlsWorkbooks.Open(strFileName)
        End If
        'Excel の Worksheets 取得
        xlsWorkSheets = xlsWorkbook.Worksheets
        'Excel の Worksheet 取得
        xlsWorkSheet = xlsWorkSheets.Item(1)
        xlsWorkSheet.Select()
        xlsApplication.Visible = ExcelVisible
      End Sub

      Private Sub WorkBook_Close()
        '終了処理
        'xlsRange の解放
        MRComObject(xlsRange, True)
        'xlsWorkSheet の解放
        MRComObject(xlsWorkSheet, True)
        'xlsWorkSheets の解放
        MRComObject(xlsWorkSheets, True)
        'xlsWorkbookを閉じる
        If Not xlsWorkbook Is Nothing Then xlsWorkbook.Close()
        'xlsWorkbook の解放
        MRComObject(xlsWorkbook, True)
        'xlsWorkbooks の解放
        MRComObject(xlsWorkbooks, True)
        'Excelを閉じる
        If Not xlsApplication Is Nothing Then xlsApplication.Quit()
        'xlsApplication を解放
        MRComObject(xlsApplication, True)
      End Sub

      'COM オブジェクトへの参照を解放
      ''' <summary>
      ''' COMオブジェクトの参照カウントをデクリメントします。
      ''' </summary>
      ''' <typeparam name="T">(省略可能)</typeparam>
      ''' <param name="objCom">
      ''' COM オブジェクト持った変数を指定します。
      ''' このメソッドの呼出し後、この引数の内容は Nothing となります。
      ''' </param>
      ''' <param name="force">
      ''' すべての参照を強制解放する場合はTrue、現在の参照のみを減ずる場合はFalse。
      ''' </param>
      Friend Sub MRComObject(Of T As Class)(ByRef objCom As T, Optional ByVal force As Boolean = False)
        If objCom Is Nothing Then Return
        Try
          If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
            If force Then
              System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
            Else
              System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
            End If
          End If
        Finally
          objCom = Nothing
        End Try
      End Sub
    ----------------------------------------------------------------------------------------------------

    上記ExcelExクラスがベースクラスで、子クラス、孫クラスがあります。
    子クラスで、Data As Microsoft.Office.Interop.Excel.Rangeと言うヶ所があるので、
    (必要無いとは思っているものの)MRComObject(Data)と入れてあります。

    ちょっと書いている途中で思いついたので、ベースクラスのみ呼び出して閉じる…
    ----------------------------------------------------------------------------------------------------
      Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        ExEx1 = New ExcelEx()
        ExEx1.WorkBook = path & "Test.xlsx"
        ExEx1.xlsApplication.WindowState = Excel.XlWindowState.xlMaximized
        ExEx1.Sheets(1)
        ExEx1.WorkBook = "Close"
      End Sub
    ----------------------------------------------------------------------------------------------------
    を実行してもやはりゴミが残ります。

    Excelを閉じた時にプロセスは終了・削除されると思っているのですが、認識が違うのでしょうか…

違反を報告
引用返信

▽[全レス13件(ResNo.9-13 表示)]
■35253 / ResNo.9)  Re[6]: Excel Com オブジェクトの増殖
□投稿者/ 魔界の仮面弁士 大御所(1492回)-(2022/11/27(Sun) 22:56:50)
  • アイコンNo35251に返信(たこさんの記事)
    > Dim check As Boolean = False
    > For Each sh In xlsSheets
    >   If CType(sh, Excel.Worksheet).Name = strSheetName Then
    >     check = True
    >     Exit For
    >   End If
    > Next

    ここがマズイですね。
    MRComObject(sh) が明らかに漏れています。


    また、 No35252 でも紹介したように、COM オブジェクトに対して For Each を使うと、
    System.Runtime.InteropServices.ComTypes.IEnumVARIANT インターフェイス
    (を実装した EnumeratorViewOfEnumVariant クラス) の解放を行うことが難しくなるので
    For ループ または Do ループ あるいは While ループ に置き換えることをお奨めします。



    > Private _ExcelVisible As Boolean = True
    > Friend Property ExcelVisible As Boolean
    >   Set(value As Boolean)
    >     _ExcelVisible = value
    >     If Not _xlsApplication Is Nothing Then _xlsApplication.Visible = _ExcelVisible
    >   End Set
    >   Get
    >     Return _ExcelVisible
    >   End Get
    > End Property

    フラグ管理したいのであれば _xlsApplication などの COM オブジェクトを公開してはいけません。
    ExEx1.xlsApplication.Visible を直接操作されたら、上記の _ExcelVisible フラグが連動しなくなりますよね?

    同様に、Range や Worksheet や Workbook などを公開するのも問題があります。
    公開したいのであれば、カプセル化した独自のマネージ クラスを Return するようにします。


    逆に、COM オブジェクトを公開する仕様とするのであれば、ExcelEx 側の役目はヘルパーライブラリに徹するものとし、
    COM オブジェクトの解放タイミングは呼び出し側に担当させる仕様の方が良いでしょう。この場合、下記の 2 つをルールとします。

    (1) プロシージャ内で生成された COM オブジェクトは、ExcelEx 自身が即座に解放する。
    (2) 呼び出し元から渡された COM オブジェクトや、呼び出し元に Return する COM オブジェクトは、呼び出し側で解放する。
違反を報告
引用返信
■35255 / ResNo.10)  Re[6]: Excel Com オブジェクトの増殖
□投稿者/ 魔界の仮面弁士 大御所(1494回)-(2022/11/28(Mon) 06:16:23)
  • アイコンNo35251に返信(たこさんの記事)
    > 問題は無い様に思えるのですが…
    Friend Sub WorkSheet_Select には、もう一つ問題点がありそうです。

    > If Not check Then
    >   _xlsWorkSheet = CType(xlsSheets.Add(), Excel.Worksheet)
    >   xlsWorkSheet.Name = strSheetName
    > Else
    >   _xlsWorkSheet = CType(xlsSheets(strSheetName), Excel.Worksheet)
    > End If
    これだと、「以前に _xlsWorkSheet が参照していた COM オブジェクト」が
    解放されなくなってしまいます。


    No35247 において、解説の最後に
    >> Dim y As Excel.Workbooks = x.Workbooks
    >> Dim z As Excel.Workbooks = x.Workbooks
    という実験コードを書いていますが、この場合、VBA や VBS とは異なり、
    .NET においては y と z が別インスタンスとなることに注意が必要です。

    この場合、COM の参照カウントは y と z それぞれに対して減じねばなりません。
    y と z の両方を RelaseComObject した場合と、どちらか一方しか
    解放しなかった場合とで、Excel の残存性を確認してみてください。

    仮に同一インスタンスを返す仕様であったとしたら、
     Trace.WriteLine(Marshal.ReleaseComObject(z)) 'ア
     Trace.WriteLine(Marshal.ReleaseComObject(y)) 'イ
    において、ReleaseComObject の戻り値から得られる残存参照カウント数が
    「イ = ア - 1」の関係となるはずですが、実際には別インスタンスであるため
    「イ = ア」な戻り値で返されていると思います。
違反を報告
引用返信
■35256 / ResNo.11)  Re[6]: Excel Com オブジェクトの増殖
□投稿者/ radian 一般人(1回)-(2022/11/28(Mon) 11:57:41)
  • アイコンちなみに、OfficeのCOMの自動管理をやってくれるライブラリもあります。
    解放漏れを特定出来ない&コードが煩雑になっている場合、
    導入を検討してみるのも手かもしれません。

    https://www.nuget.org/packages/NetOfficeFw.Excel/
    https://github.com/NetOfficeFw/NetOffice
違反を報告
引用返信
■35257 / ResNo.12)  Re[7]: Excel Com オブジェクトの増殖
□投稿者/ たこ 一般人(19回)-(2022/11/28(Mon) 22:38:47)
  • アイコンNo35252に返信(魔界の仮面弁士さんの記事)
    No35253に返信(魔界の仮面弁士さんの記事)
    No35255に返信(魔界の仮面弁士さんの記事)
    No35256に返信(radianさんの記事)

    魔界の仮面弁士様、radian様、返信ありがとうございます。

    返信が前後しますが、まずはradian様ご紹介ありがとうございます。
    どうしようも無くなった時は検討させて頂きます(^^ゞ

    余談にはなりますが…
    元々私、プログラミングは全部独学でして、スキルアップの為に今回の質問をさせて頂いています(^^ゞ
    (いつもはどうしようも無くなって質問させて頂いていますが…(^^ゞ)
    まだしっかりと解ってる訳では無いですが、VB6.0からオブジェクトの概念を解る様になるまでは苦労しました^^;

    最終的には会社で5年分くらいExcelで見積書が溜まっていますので、これをデータベース化するのが目的です。。。
    最初はExcel VBAで5年分の見積書の内容をまとめようかと思っていましたが、クラスの概念を覚えてしまうとクラスを使った方が楽なので(^^ゞ
    VB6.0やVBAにもクラスはありますが、使い方が良く解りません…
    …と言う訳でVB.NETで…(^^ゞ

    お気持ちは有難く頂戴致しました。
    ありがとうございます。



    今回、いろいろ調べてやっとExcelのオブジェクトモデルを発見出来ました。
    https://learn.microsoft.com/ja-jp/office/vba/api/overview/excel/object-model
    VBAと同じなのですね…
    当たり前と言えば当たり前ですが…

    Option Strict Onも調べました…
    https://atmarkit.itmedia.co.jp/fdotnet/vb6tonet/vb6tonet26/vb6tonet26_03.html

    DirectCast、CTypeの違いも調べました…
    http://vb.navi-ch.net/2015/07/18/post-118/
    https://learn.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/operators/directcast-operator



    さて、本題に戻ります。

    No35252に返信(魔界の仮面弁士さんの記事)
    >>  Private _xlsApplication As Excel.Application = Nothing
    >>  Friend ReadOnly Property xlsApplication As Excel.Application
    >>    Get
    >>      Return _xlsApplication
    >>    End Get
    >>  End Property
    > これではあまり意味が無いと思いますよ。結局のところ、
    >  Friend ReadOnly xlsApplication As Excel.Application
    > な読み取り専用フィールドと、さほど変わらないように見えます。
    >
    >
    > COM オブジェクトを直接公開してしまうと、ExcelEx の外部で
    >  ExEx1.xlsApplication.Workbooks.Add()
    > などと書かれてしまえば、COM オブジェクトの解放漏れに繋がります。
    >
    > IDisposable としてカプセル化するのであれば、Excel の COM オブジェクトは
    > 外部からは直接操作できないようにして、すべてクラス内に隠蔽します。
    > 戻り値と返すのも COM オブジェクトではなく、.NET のマネージオブジェクトにします。

    全てをクラス内でやってしまう…と言う考え方で良いのでしょうか…
    例えば…
    -----------------------------------------------------------------
    Private _xlsApplication as Excel.Application = Nothing

    Private _ExcelVisible As Boolean = True
    Public Property ExcelVisible As Boolean
      Set(Value as Boolean)
        _ExcelVisible = Value
        If value then
          _xlsApplication.Visible = True
        Else
          _xlsApplication.Visible = False
        End If
      End Set
      Get
        Return _ExcelVisible
      End Get
    End Property
    -----------------------------------------------------------------
    …の様な感じで…

    >>  _xlsWorkSheet = xlsApplication.Sheets.Add()
    > この処理には、問題点が 2 つあります。
    >
    > 1 つは「.」による COM オブジェクトの連続呼び出しであり、
    > Sheets プロパティから返されるコレクションの解放が漏れています。
    Excel.Applicationオブジェクト(COMモデル)の中の、Application.Sheetsプロパティ…あれ?w
    https://learn.microsoft.com/ja-jp/office/vba/api/excel.application.sheets
    COMオブジェクトの場合は(COMオブジェクトの)プロパティの解放も必要と理解して良いのでしょうか…

    >  Dim obj1 = 対象ワークブック.Sheets 'これは Sheets 型        …と言う事は Dim obj1 As Excel.Sheets
    >  Dim obj2 = obj1(strSheetName) 'これは Object 型となることに注意   …と言う事は Dim obj2 As Object
    …で合ってますかね^^?
    ここの理解はまだ追い付いていません(>_<)

    > ただし厳密にいえば、xlsSheets によって列挙されるシートが Excel.Worksheet である保証はありません。
    > Excel.Chart や Excel.DialogSheet が列挙される可能性もあることは頭の片隅に置いといてください。

    …と言う事は…
    -------------------------------------------------------------------------------------
    Friend Sub WorkSheet_Select(strSheetName As String)
      Dim check As Boolean = False
      For x As Integer = 1 to _xlsSheets.Count
        If _xlsSheets(x) Is Excel.Worksheet then                '← 怒られました^^;
          If CType(_xlsSheets (x), Excel.Worksheet).Name = strSheetName Then
            check = True
            Exit For
          End If
        End If
      Next
      If Not check Then
        _xlsWorkSheet = CType(_xlsSheets.Add(), Excel.Worksheet)
        _xlsWorkSheet.Name = strSheetName
      Else
        _xlsWorkSheet = CType(_xlsSheets(strSheetName), Excel.Worksheet)
      End If
      If SheetVisible Then _xlsWorkSheet.Select()
    End Sub
    -------------------------------------------------------------------------------------

    下の方に書いてありました^^;
    >   Dim ws = DirectCast(xlsSheets(n), Excel.Worksheet)
    これだと『WorkSheet』以外はNothingになるのでしょうか…

    (DirectCastは明示的な型変換と書いてありました…
    http://vb.navi-ch.net/2015/07/18/post-118/
    -------------------------------------------------------------------------------------
    サンプルソース
    Dim a As Object = 3.14
    Dim b As Integer = DirectCast(a, Integer)
    MsgBox(b)
    End Sub
    End Class
    実行結果
    メッセージーボックスも表示されません。
    -------------------------------------------------------------------------------------

    頭大パニック中…
違反を報告
引用返信
■35258 / ResNo.13)  Re[8]: Excel Com オブジェクトの増殖
□投稿者/ たこ 一般人(20回)-(2022/11/28(Mon) 23:06:02)
  • アイコンNo35257に返信(たこさんの記事)

    ちょっとした実験をしてみました。
    --------------------------------------------------------------------
    Dim w As Excel.Worksheets
    Dim s = w.Item(1)     '←WorkSheetオブジェクトのItemなので、当然WorkSheet型だと思っている
    Dim n = CType(s, Excel.Worksheets).name    '←怒られる…
    --------------------------------------------------------------------

    Dim s As Excel.Worksheets = w.Item(1)   '←やっぱり怒られる…
                         'Option Strict On では'Object'から'Worksheets'への暗黙的な変換は許可されていません。
                         'ReadOnly Property Excel.Wroksheets.Item(Index As Object) As Object

    Dim s As Object = w.Item(1)        'これが正解の様だ…
                         'ここは戻り値がObjectなので理解出来る。

    Dim n = CType(s, Object).name       '←怒られる…
                         'Option Strict On では、遅延バインディングを使用できません。
    一体何の型にキャストすればシート名が取得できるのだろう…

    >『.』の連続」が見えにくくなる
    .を分解するのも苦労します(>_<)

    あ…そう言えばと思い。。。

    Dim w As Excel.Worksheets
    Dim s As Object = w.Item(1)
    Dim sh As Excel.Worksheet = CType(s, Excel.Worksheet)
    Dim n As String = sh.Name

    怒られなくなりました!

    この場合、MRComObjectをしなければならないのは…
    w、s、shで合っていますでしょうか^^?


違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-9] [10-13]






Mode/  Pass/


- Child Tree -

2024/10/30(Wed) 19:50:06 に作成されたキャッシュを表示しています。
生のデータを表示する | キャッシュを最新にする