一人情シスのつぶやき

名古屋の中小企業で一人情シスをしている作者が、日々の業務で思うことをつぶやきます。

WindowsFormでイベントを駆使して入力チェック等を行う場合のポイント

  • すべてのイベントハンドラを一括で登録、削除する関数を作成する
  • すべてのイベントハンドラの最初で削除し、最後に再登録する
    • イベントの多重起動(Leaveイベント内で別ControlのFocusを実行して再度Leaveが実行される、等)を防ぐにはこれが確実
    • 関数のreturn部分が複数あって複雑な場合は、try-finallyのfinally内で再登録する
    • イベントハンドラから呼び出す関数内で削除,登録処理を行うと、その関数の呼ばれ方によって再登録が多重に行われてしまう可能性がある。関数を使う場合もイベントハンドラの中で直接一括削除、再登録を行う

DataRow.Field<int> とConvert.ToInt32 の違い

DataRow.Field とConvert.ToInt32 の違いについて、 int がstringになった場合でも同様。

DataRowの値がDBNullかどうかで分ける場合に var val = (dr["name"] == DBNull.Value) ? "" : Convert.ToString(dr["name"]) とやっていたのだが、

var val = dr.Field<int?>("name") ?? "" と書けるという記事を発見し、早速使ってみたのだが...

Field版では、データがdecimalの場合にInValidCastExceptionが発生してしまう。値の範囲がintの範囲に収まっているかどうかは関係ない。 利用しているデータがdecimalの桁数指定で定義している箇所がほとんどという性質のため、これでは全く使えないと判明した...

ただ、Convert.ToString(DBNull.Value) はstring.empty(空文字)に、Convert.ToInt32(DBNull.Value)は0になるので、これがOKであればこれが最も手っ取り早いとわかった。

DataRowのFieldやGetValueOrDefaultのようなジェネリクスメソッドは型変換の範囲が厳しく、逆にConvert系はおおらかなのだろう。

WindowsのMariaDBメジャーバージョンアップ後の運用の注意

WindowsMariaDBを10.2 -> 10.4のようにメジャーバージョンアップする場合について。

バージョンアップ自体は公式サイトの手順に従って行えば良い。インストーラにより、上記の場合はバイナリはC:\Program Files\MariaDB 10.4、データはC:\Program Files\MariaDB 10.2を参照するようになる。MySQLサービスの実行パスは

"c:\Program Files\MariaDB 10.4\bin\mysqld.exe" "--defaults-file=C:\Program Files\MariaDB 10.2\data\my.ini" "MySQL"

のようになる。

で、時間があるのでデータもバイナリも10.4のフォルダにするためにバックアップを取得した上で10.4をアンインストール、再度10.4をインストールすると、サービスが起動しない。 原因は上記実行パスのサービスがアンインストール時も消されずに残ってしまうためのよう。 MariaDBをすべてアンインストールした状態でsc delete MySQLを実行して残ったサービスを削除し、再度インストールすると正しい実行パスのサービスのエントリが生成される。

Accessのレポート機能の活用

内製のシステムを、Accessベースから.Netに移行している。 その際に最大のネックになるのはレポート機能。

Accessのレポート機能は正直相当優秀だと思う。.Netの有償アプリで同等の機能を持つものを選定すると、開発者向けライセンスが100万レベルのものになってしまう。 それが、Officeの上位ライセンスに付属し、ランタイムだけなら無償で利用できる。

一方でネックはコードの開発生産性の低さ。VBAの文法は古めかしいし、何よりテキストではないのでGitで管理できない。

上記のいいとこ取りとして、Accessファイルのレポート機能だけを利用する方法を考えている。 Accessファイル側はレポートとレコードソースとなるテーブルのみ保持し、起動時にそのレポートが初期表示されるように設定しておく。

.Netのプロジェクト側では常に配布するコンテンツとしてAccessファイルを保持し、ADO経由でレコードソースとなるテーブルにデータを設定する。 その後外部プロセスとして該当のAccessを起動すると、レポートが表示される。 外部プロセスなので細かい制御はできないが、用途によっては十分だろう。

帳票数が多いアプリではきついかもしれないが、移行できない少数のレポートを活用する場合には十分かと思われる。

NuGetライブラリ整理直後に謎のエラー

NuGetで使用するライブラリをVisualStuidoの管理画面より変更(削除->追加)し、合わせて削除したライブラリに依存するライブラリを削除したところ、dllが存在しない旨を表すエラーが発生。 そのdllを見ると、削除したはずのdll。

App.configを見ると、その削除したはずのdllに関するdependentAssemblyエントリが合ったため、バックアップを取得した上で該当箇所を削除したところエラーは出なくなった。

Visual StudioでNugetライブラリを削除する場合には、設定ファイル(App.config)には連動されない場合があるらしい。

Visual Studio 2017でReport Viewerの表示、編集ができない

Visual Studioで久しぶりにReport Viewerを編集しようとしたのだが、右クリックしても何も表示されない。 右上に右向きの矢印が表示されるはずなのだが、それもない...

新しいフォームを作ってReportViewerをドロップしたところ、何も表示されない。

stackoverflow.com

を参考にInitializeComponentにコードを追加すると表示はされるが、やはり一切編集できない。

編集したい理由は、rdlcファイルを指定がエラーとなっていて編集し直したかったため。this.reportViewer1.LocalReport.ReportEmbeddedResource にrdlcファイルを直接指定する方法を試してみたが、GUIで指定したほうが有効になっているためか全く効かない。

最近.Net Coreのプロジェクトを作った際、Visual Studio CodeとIntellisenseがらみで干渉したため、いったんアンインストールしたことがあった。その際に設定がおかしくなったのかもしれない。 Visual StudioをいったんアンインストールしてOS再起動後にインストール。

Visual Studio 2017(Pro)をインストール後、拡張機能Microsoft RDLC Report Designer」をインストール。 Microsoft.ReportingServices.ReportViewerControl.Winformsライブラリを、Visual Studio内のNuget管理画面にて、下げられる最低のバージョン140.337.80まで下げると編集メニューが表示される!!

ただ、既に作成済みのreportViewerはうまく動作しないため、いったん削除して同名で再作成して再配置。 その後、最新バージョンまで上げたが、正常に動作している。

一旦バージョンを下げることでキャッシュか何かがクリアされたのか? 原因不明。

MySqlBulkLoaderでの取込結果が合わない

C#MariaDBに接続する際にMySqlConnectorを利用している。

大量のデータを取り込む必要があったため、MySqlBulkLoaderで取り込んだところ、なんかゴミデータみたいのが入るうえに数字も合わない。 よくよく調べたところ、前段のCSV出力個所と、取込時の設定にミスがあった。

CSV出力時の改行の削除

CSV出力にはCSVHelper.CsvWriterを使用しているのだが、Fieldに改行があるとそのままCSVに出力される。CSVファイルは1行1データを前提としているので、ゴミデータが発生する原因になる。

csv.WriteField(col.ToString().Replace("\r", "").Replace("\n", ""))

のように除去することで回避できた

FieldQuatationCharacterの設定

FieldTerminator, LineTerminator は普通に設定したのだが、FieldQuatationCharacter を設定しないと、CSVHelperがせっかく括弧で囲んでくれた中にカンマが含まれていると、そこで区切られてしまう。

mySqlBulkLoader.FieldQuotationCharacter = '"';

と指定することで回避できた。

MySqlConnector の MySqlBulkLoader は上記のような不具合で項目数など合わなくてもエラーなしで無理やり取り込むのが困ったところ...