WPFのDataGridでコンボボックスを表示するのにちょっと詰まってしまったのでメモ。
DataGridにコンボボックスを表示する
VBA 画面タイトルを指定しIEを待機する
VBAで基幹システム(Web)を操作するためのRPAツールを作っている。
画面に値を入力してから、内部処理が完了するまでの間に動作を待機する必要がある。一律でSleepを入れると無駄な時間が発生して動作が不安定になるのでIEの動作が完了するまで待機する処理を実装する。
うまく作れればExcelで簡単なRPAツールを作ることができる。マウス操作、クリック、指定した画面をアクティブにする、コピー、貼り付け、ぐらいは問題なく関数は作れているのであとは組み合わせるだけ。
フリーソフトをインストールする必要がないのでExcelだけ入っていれば使える簡易なRPAになる。のんびりと作っていこうと思う。
<使い方>
・標準モジュールに貼り付け
・GetIEWindowTitlesでタイトルを確認
・WaitIEの引数に確認したタイトルを指定(部分一致)
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'IEの動作を待機する
Public Function WaitIE(ByVal strCaption) AS Boolean
Dim shells As Object
Dim shell As Object
DIm tgtIE As Object
For i = 0 To 100
Set shells = CreateObject("Shell.Application")
For Each shell In shells.Windows
If TypeName(shell.document) = "HTMLDocument" Then
If InStr(shell.document.Title,strCaption) > 0 Then
Set tgtIE = shell
Exit For
End If
End IF
Next
If Not tgtIE Is Nothing Exit For
Sleep 100
Next
If tgtIE Is Nothing Then
WaitIE = False
Else
'IEが動作中の場合は待つ
Do While tgtIE.Busy = True Or tgtIE.readyState <> 4
DoEvents
Loop
Sleep 100
WaitIE = True
End If
End Function
'WaitIEで指定できる画面を全て取得する
Public Function GetIEWindowTitles() As String
Dim shells As Object
Dim shell As Object
Dim strValue As String
GetIEWindowTitles = ""
Set shells = CreateObject("Shell.Application")
For Each shell In shells.Windows
If TypeName(shell.document) = "HTMLDocument" Then
If strValue <> "" Then strValue = strValue & ","
strValue = strValue & shell.document.Title
End IF
Next
Set shell = Nothing
GetIEWindowTitles = strValue
End Function
TesseractOCRアプリケーションの作成について<手順4.OCRManager.exeを作成>
1.NugetでOpenCvSharp4をインストールする
TesseractOCRアプリケーションの作成について<手順3.TesseractOCR.exeを作成>
<TesseractOCRアプリケーションの画面一覧について>
・メイン画面・・・ジョブの状況を一目で確認できるようにする・帳票定義一覧・・・帳票定義の内容を一覧で表示
・帳票定義詳細・・・帳票定義の詳細を更新・削除
・読取枠定義・・・帳票定義の読取枠の定義を更新・削除
・ジョブ定義一覧・・・ジョブの一覧を表示
・ジョブ定義詳細・・・ジョブの内容を登録・削除
・ジョブ結果項目修正・・・OCRの結果を確認、修正
<メイン画面>
<読取枠定義>
TesseractOCRアプリケーションの作成について<手順2.WPFアプリケーションの画面作成方法(2.CsPage作成とスタイルの共通化)>
<CsPageの作成方法について>
プロジェクトを右クリックして、新しいファイル、ページ(WPF)を選択する。
新しく作成したPageのxamlを修正します。
CsWindowの時と同じで、「xmlns:controls="clr-namespace:TesseractOCR.controls"」を追加して、「<Page」を「<controls:CsPage」と修正します。「pg01_0100_Main.xaml.cs」へ移動し、継承元のクラス名を「CsPage」へ修正するとともに「using TesseractOCR.controls;」を追加します。
また試しに、F1キーを押下したときの処理を記述します。
BaseWindowプロパティにインスタンスが設定されるのは、CsPageクラスがインスタンス化された後なので、PageのLoadイベント後にイベントハンドラを設定します。※コマンドならこんな方法じゃなくていいと思いますが・・・。
新しく作成したpg01_0100_Main.xamlに試しのためのTextBlockコントロールを置いて、TextBoxを配置します。
controls.BaseWindow window = new controls.BaseWindow(new pg01_0100_Main());
window.Show();
画面)
コントロールのスタイルについてXAMLを利用するとコントロールの意味に応じたスタイルを共通で設定することができます。スタイルの継承も可能なので、下記のような形式でスタイルを一度作ってしまえば、様々なプロジェクトで利用できるのではないかと思います。
BaseResource.xaml・・・各コントロールの基礎スタイルを定義します。
ControlResource.xaml・・・BaseResource.xamlに定義されているスタイルを継承し、コントロールごとのスタイルを定義します。
ProjectResource.xaml・・・ControlResource.xamlに定義されているスタイルを継承し、プロジェクトごとのスタイルを定義します。
新しいプロジェクト(別の業務アプリを作成)するときには「BaseResource.xaml」「ControlResource.xaml」はほぼそのまま利用し、「ProjectResource.xaml」については仕様に合わせて再定義することで流用可能です。
例)
BaseResource.xamlに「TextBoxStyleBase」として「TextBox」のフォーカス時の背景色の設定やフォントなどを設定します。
ControlResource.xamlに「TextBoxStyleBase」を継承して、「通常のテキストボックス(NormalTextBox)」「複数行可能なテキストボックス」のスタイルを定義します。
ProjectResource.xamlにControlResource.xamlで定義した「通常のテキストボックス」を継承して、MaxLengthや入力文字制限を行うスタイルを定義します。
「TextBoxStyleBase」-> 「NormalTextBox」->「txtRptIdStyle」
※->:は継承の意味
こうしておくことで、業務アプリなどでよくある「得意先CD」「得意先名」といった意味のあるコントロールにすべて共通したスタイルを定義することができます。
桁数の変更があったとしてもXAMLを修正するだけですぐに対応できます。
<手順>
新しいフォルダーを作成し、フォルダ名を変更します。フォルダ名:resource
リソースディクショナリを追加します。 追加後のフォルダ販売管理システムや会計管理システムそのほかの業務アプリでは同じ意味を持つ項目がいろいろな画面に置かれるので桁数のチェックや右寄せ左寄せなど本来大事にするべき業務ロジックとは関係のないところのテストや設定が必要になってしまいます。そのあたりが楽になるので、こういう機能はあるとありがたいですね。使いこなせるかというところはちょっと慣れが必要ですが、まぁ一週間毎日8時間悩んでいればいやでも身につくので頑張りましょう。
TesseractOCRアプリケーションの作成について<手順2.WPFアプリケーションの画面作成方法(1.BaseWindow作成)>
<Windowの構成について>
F1~F12キーをファンクションキーとして利用する構成に慣れているので、なんとか慣れ親しんだ操作法で作れるように構成を考える。
業務用のソフトを作る期間が長かったので、ついついこの構成で作るように考えてしまう。
<イメージ>
Webブラウザみたいな感じでWindowの中にFrameコントロールを設置し、各画面の設計はPageクラスを派生したCsPageで行う。
WindowコントロールはコンストラクタでFrameに渡されたCsPageクラスをNavigateメソッドで呼び出す。
※Windowがブラウザ、PageがWebページのイメージ
<手順1 必要な継承コントロールの作成>
WPF(.Net Core)のプロジェクトを作成し、プロジェクトを右クリックして「新しいフォルダー」を作成し、「controls」と名前を付ける。次にこのフォルダを右クリックして「クラス」を追加していく。
クラスの名前はそれぞれ「CsButton」「CsCheckBox」「CsComboBox」「CsDataGrid」「CsPage」「CsTextBox」「CsWindow」で合計7つ。
次にそれぞれのクラスファイルに対して継承元のクラスを記述していく。
例)修正前の「CsCheckBox」
内容の記述については今後の手順で必要に応じて行っていく。
<手順2 BaseWindowの作成>
次にPageを表示する大本となるWindowを作成する。
CsPage.csへ移動し、「public BaseWindow BaseWindow { get; set; }」を追加します。
CsButton.csへ移動し、「using System.Windows.Automation.Peers;」「using System.Windows.Automation.Provider;」を追加し、下記のソースを追加します。
/// <summary>
/// Clickイベントを発生させる
/// サンプル:https://blog.xin9le.net/entry/2013/10/27/195614
/// </summary>
public void PerformClick()
{
/// バインドしているコントロールに変更通知を送る必要があるのでフォーカスを移動
this.Focus();
var provider = new ButtonAutomationPeer(this) as IInvokeProvider;
provider.Invoke();
}
真っ白な画面でボタンだけが配置されています。ちょっとわかりにくいのでBaseWindow.xamlのFrameコントロール(Name=MainFrame)のBackgroundを変更します。
TesseractOCRアプリケーションの作成について<手順1-1.バーコード読み取り機能を追加>
1.ZXing.NetをNugetでインストールする
PowerShellでWPFアプリケーションをBindingするときの注意点
1.PowerShellでWPFアプリケーションのBindingについて マニアックだけどPowerShellでWPFアプリケーションを作っている。INotifyChangedを実装したいけど、PowerShellにはgetterやsetterがないので通知が発行できない。 そ...
-
TreeListView上でコンボボックスを利用するときにフォーカスのあるコンボボックスの色をイベントで変えようとしたけど上手くいかなかった。 色々と調べているとXaml側のテンプレートをいじる必要があるみたいだったので、いろいろとやってみた。 とりあえず、コンボボックス...
-
PDFファイルが大量にあるため、中身を検索する方法がないか調べたときのメモ ・外部のdllは必須っぽい ・PowerShell単独や.NET Frameworkなどの利用だけではどうにもならない ちょっと調べるだけでもiTextSharpが使えそうだったので利用する。 1....
-
Excelマクロでカスタマーバーコードのもとになるデータを作る必要があったので、調べてみたらいい古い記事だけどわかりやすいプログラムを記載しているブログがあった。 https://shiganaisenotes.blogspot.com/2011/11/blog-post.ht...

