2016年09月15日

VBAのプロジェクトパスワードを回避していると、VBAのデバッグ時に「呼び出しの履歴」が開かないという副作用があることを発見

Is there a way to crack the password on an Excel VBA Project? - Stack Overflow

上記のソースコードを コピペして、Sub unprotected() を呼び出すと
開いているすべてのVBAプロジェクトのパスワード入力ウィンドウが回避されます。

さて、その状態でVBAの開発は普通にできるのですが、デバッグ時に 「呼び出し履歴」のダイアログが表示されなくなることに気が付きました。
2016-09-15_214802.png
Sub unprotected() を呼び出さない場合は 問題なく使えるため、犯人は明らかでした。

というわけで、メモ。

2016年08月29日

Oracle Client インストール不要、単体で DB接続可能な Oracle ODP.NET, Managed Driver。

NuGet Gallery | Official Oracle ODP.NET, Managed Driver 12.1.24160419

昔のODAC(Oracle.DataAccess.*)ドライバーを使ったときの接続文字列と同じだったから、今回の ODP.net の移行は ファクトリークラス名称を変えるだけ(Oracle.ManagedDataAccess.*)で対応完了した。(その後の処理はすべてインターフェース経由なので 実装依存がないのだ)

Oracle Data Provider for .NET

DB2にはそういう(ポータブルな).net のプロバイダーはいまだにないんだよね。

Oracle Client(ODP.NET)を手っ取り早くインストールする方法について - 素敵なおひげですね

2016年08月18日

[.net] DateTime.Now の 精度はミリ秒がぎりぎり、マイクロ秒の精度はいい加減すぎる。そこからの精度の高いDateTimeの作り方。

C# time in microseconds - Stack Overflow

DateTime(Date)オブジェクトは long 型の Ticks の数によって一意に決まりますが、この DateTime.Ticks が 実際の時間の経過に対して マイクロ秒のオーダーで 追従していないことが発覚しました。

DateTimeオブジェクトを HH:mm:ss.fff の初期式で表示すると 最後のミリ秒の数値が以下
11:15:59.121
11:15:59.123
11:15:59.123
11:15:59.123
11:15:59.123
11:15:59.126
のように
123ミリ秒の表示が続くことが結構あったのですが、マイクロ秒の精度が十分にあるStopWatchオブジェクトで経過秒数を見ると DateTime.Now はミリ秒のオーダーからして精度不足という事実が分かりました。

しかしこれ DateTime の精度が悪いのではなく、Now で生成するときのロジックがミリ秒近辺の精度を無視して適当に時刻を生成しているようです。

そこで以下のようなプログラムを書いて検証してみました。

Module Module1
Sub Main()
Dim sw As New System.Diagnostics.Stopwatch()
Dim fw As New System.IO.StreamWriter(Format(DateTime.Now, "yyyyMMdd_HHmmss.fff") & ".txt", False)
Dim sb As New System.Text.StringBuilder(50 * 3000)
Const LC As Integer = 30000

sw.Restart()
For i As Integer = 1 To LC
sb.Append(Format(DateTime.Now, "HH:mm:ss.ffffff, "))
Next
sw.Stop()
Dim msg As String = String.Format("{0}ticks,{1}msで{2}個のDateTimeを生成", sw.ElapsedTicks, sw.Elapsed.TotalMilliseconds, LC)
fw.WriteLine(msg)
fw.WriteLine(sb.ToString)
sb.Length = 0
fw.Flush()
fw.Close()
fw.Dispose()
Console.WriteLine(msg)
Console.In.ReadLine()
End Sub
End Module


上記のプログラム実行にて生成された3万個の時刻を重複を省いたところ以下のように取得できました。(25個の異なる時刻でした)
マイクロ秒の位置の数値がかなり適当であることはよくわかるでしょう。(ほぼ1ミリ秒の間は常に同じ時刻となっている)
83649ticks,23.8003msで30000個のDateTimeを生成
22:00:37.188515
22:00:37.189517
22:00:37.190517
22:00:37.191519
22:00:37.192520
22:00:37.193521
22:00:37.194523
22:00:37.195524
22:00:37.196526
22:00:37.197526
22:00:37.198528
22:00:37.199529
22:00:37.200530
22:00:37.201532
22:00:37.202533
22:00:37.203534
22:00:37.204535
22:00:37.205536
22:00:37.206537
22:00:37.207539
22:00:37.208540
22:00:37.209541
22:00:37.210543
22:00:37.211545
22:00:37.212545


これを以下のように、時刻の初期値は DateTime.Now であるものの、
そこから先は 正確なタイマーを使って 時差を .AddTicks していくことでマイクロ秒オーダーの正確さを
実現できました。オブジェクトはDateTime のまま、精度向上です。
赤字が修正箇所。TimeSpanのTicksは一般化されたものであり、マシン個別のStopwatch.GetTimestampの Ticks の数値は互換性がないのでそれをアジャストするロジックが入ります。

Module Module1
Sub Main()
Dim sw As New System.Diagnostics.Stopwatch()
Dim fw As New System.IO.StreamWriter(Format(DateTime.Now, "yyyyMMdd_HHmmss.fff") & ".txt", False)
Dim sb As New System.Text.StringBuilder(50 * 3000)
Const LC As Integer = 30000
Dim startDt As DateTime = DateTime.Now
Dim startTick As Long = System.Diagnostics.Stopwatch.GetTimestamp

sw.Restart()
For i As Integer = 1 To LC
Dim addTick As Long
addTick = CLng(TimeSpan.TicksPerSecond * (Stopwatch.GetTimestamp - startTick) / Stopwatch.Frequency)

sb.Append(Format(startDt.AddTicks(addTick), "HH:mm:ss.ffffff, "))
Next
sw.Stop()
Dim msg As String = String.Format("{0}ticks,{1}msで{2}個のDateTimeを生成", sw.ElapsedTicks, sw.Elapsed.TotalMilliseconds, LC)
fw.WriteLine(msg)
fw.WriteLine(sb.ToString)
sb.Length = 0
fw.Flush()
fw.Close()
fw.Dispose()
Console.WriteLine(msg)
Console.In.ReadLine()
End Sub
End Module


この結果は 「63922ticks,18.1875msで30000個のDateTimeを生成」で、3万個のうち1万5千個は異なる時刻を生成できました。( 書式を ffffff(1マイクロ秒の精度) から (0.1マイクロ秒の精度の)fffffff にすると 3万通りの時刻を生成できました)。
なお、生成速度はばらつきがあるので 「精度が高いのに速い」という事ではありません。

fffffff が.net の DateTimeに対して Format 指定可能なもっとも細かい単位 の 1Tick (=100 nano second = 0.1 マイクロ秒) となります。

2016年07月05日

自作のエクセルVBAマクロの過負荷?でエクセルが調子悪くなった、の図

2016-07-05_222722.png

セル範囲選択などしても、選択範囲が描画されない
マウスカーソルがずっと砂時計
エクセルが終了できない
右クリックメニューのアイコンが侵入禁止のやつに代わっている

もうここまで来ると プロセスを強制終了するのみ。

2016年06月16日

順調に手元のエクセルVBAマクロが太り、デコンパイルしても1700KBを下回らなくなった。

今年の3月にはDecompileして900KB程度だったExcelのマクロブックが今はおんなじことしても1200KB以下にならない。: NN Space BLOG-NN空間ブログ

日々コードは増え続ける一方で、あんまり削減されることがないからなぁ。

一時期デコンパイルしても2000KBオーバーの時があったのですが、関数をエクセルの関数として呼び出せないように(呼び出す必要がないので)、
Option Private Module ' ユーザー定義に出さない
という宣言を各モジュールに追加したところ、その時限りで大幅なダイエットに成功。その後また太りだしている。

今後はもう、増え続けるしかないのだろう。

今のところ、サポートEXCELを2000からとしているのですが、2007以降に限定する決心ができれば 圧縮形式のブックに変更してもうちょっとサイズダウンできると思っている。

2016年05月30日

ソースコードが仕様

ドキュメントをなくしてもうまくいく? 〜 人に依存するリスクへの対処とは | Social Change!

ソースコードから仕様だけを読み取るには、ソースコードができるだけビジネスロジックだけ、ビジネスルールだけを記述するようにできていることが望ましい。それ以外のフレームワーク的要素とかは、できるだけ隠蔽し、他のビジネスロジックと共通化する。

ってことを考えて独自フレームワークとかライブラリを作ってきた。でも最近は人様のソースコードを読む機会も増えて、自己満足の世界がとても狭いことに何度も何度も気づかされて方向性がぶれてきそうな感じ。

ドキュメントの構造化による,良いドキュメントの作成方法:新春特別企画|gihyo.jp … 技術評論社

2016年04月27日

VBAでもここまでできるんだなという事を再確認したすごいまとめっぷりの記事

昨日までJavaJavaしてた人がいきなりExcelのVBAを実装する羽目になったときのためのメモ - Qiita
↑これ。

基本から応用まで全部入り!みたいな。 確かにJavaからVBAに入る人はどこまでがVBAでできて、どこからダメになるのかがよくわかるのではないかしらん。

個人的にVBAでここまでできないのはいまいち!というものを上げると
・オブジェクト型変数に代入するには setステートメントを使用しなければならないこと
・変数の宣言と同時に初期化ができないこと
・return で戻れないこと
などがあげられますね。

VBAは過去のオフィスのVBAとの互換性のために、あえて進化しない道を選んだのではないかと思うほど 変わっていない。

だが、いろいろなことはVBAでできる。
リンク抜粋
Release VBA-Web v4.0.21 ・ VBA-tools/VBA-Web ・ GitHub

コンストラクタで引数を入れたい | 愚者の経験

2016年04月03日

EXCEL 2010 VBA Modal Form 表示の時に変な挙動を見つけてしまった

確認したのは Windows7+EXCEL 2010 の環境。(Windows10+Excel2013 では発生しない)。

確認の方法はいたって簡単。VBAでどんなフォームでもいいので、
Form1.Show vbModal
として呼び出してモーダル表示しておく。(この操作をVBAエディタから行ったのならばいったんここでVBAエディタを閉じておく)

そして、タスクバーに表示されている起動中のエクセルアイコンを右クリックするだけ。

すると、なぜかVBAエディタが表示されてデバッグ表示で中断した状態になる。実行を中断するとモーダルフォームが消えてしまう。気を付けて実行を継続(F5)すると フォームは生きたまま残る。

なんじゃこれ、この挙動に意味があるとは到底思えない。

2016年03月24日

vb.net に悪いところがあっても使い続けます

VB.NETが糞であると思うたった一つの理由。あと最弱無敗の神装機竜 - ぐちったっていいじゃないSIerだもの、あと・・・

・大文字小文字を区別しない

たったこれだけのことだけど確かにねぇ。そうだね。

VB特有の Option ステートメントか何かで 厳密に区別するようにできないものかね。もしくは 宣言の名前の前に「この名前は大文字小文字を区別する」のような 書き方ができるようになるといいのかも。いかにもVB脳的な考え方だね。MustInherit とか Overloads とかいちいち書かせることによる区別だね。

まあでもVBのこの特徴のおかげで大文字小文字気にせずにタイプして自動修正で楽ができるからこれはこれでいいと思っていたよ。

むしろ大文字小文字の違いだけで別のもの扱いされてしまうとかえって紛らわしいことがあるしね。

VB.net が C# と比べて機能的に不遇なのは認める。

正直にねいうとね、C#のサンプルコードしかなくてもそこからVB.netに書き下すのがへっちゃらなくらいになってしまっているのですよ。
だから何も困らない。

2016年02月29日

フォルダ・ファイル

ファイルシステムにおける名指しと解釈:XPathを使って - 檜山正幸のキマイラ飼育記

全然関係ないですが、Windows のレジストリでは \のあるなし が明確に使い分けされます。
\がある場合はキーで、無い場合は キー配下のエントリーです。

レジストリにキーまたはエントリを追加する

「EXCEL VBA」2つのセルの間の長方形Rangeを取得する方法を今まで知らんかった。。。

cells(1,1) と cells(3,5) の間の Rangeオブジェクトがほしい場合

昨日までだと

cells(1,1) -> "A1"
cells(3,5) -> "E3"

すなわち 必要なRange -> Range("A1:E3")
みたいな回りくどいことをしていたが、

なんと、 一発でできることが分かった。(ExcelVBAでできて 当たり前のことだったのですが)
Range(cells(1,1), cells(3,5)) と記述することで Range("A1:E3") と等価です。
尚、当然ながら 2つのセルは同じシートに存在する必要がある。つまり Range( sheet1.cells(1,1), sheet1.cells(3,5)) は正しく動作するが Range( sheet1.cells(1,1), sheet2.cells(3,5)) はエラーになる。


こんな簡単なことだったのに、どうして今まで気が付かないまんまあまつさえも「 ColumnIndexから 列番号のアルファベットを取得する関数」を作って喜んでいた自分が恥ずかしい。

恥のついでにその自作関数を置いておきますね。

Public Function idx2Alphabet(ByVal colIdx As Long) As String
Dim alphaBeta As String: alphaBeta = ""
Dim col As Long: col = colIdx
Dim fx As Long
Do While col > 0
fx = (col - 1) Mod 26
If fx >= 0 Then
alphaBeta = chr(64 + (fx + 1)) & alphaBeta
col = (col - (fx + 1)) / 26
End If
Loop
idx2Alphabet = Trim(alphaBeta)
End Function

テストする場合は
idx2Alphabet(2147483647) -> FXSHRXW 'Long型の上限
idx2Alphabet(16384) -> XFD 'Excel 2010 の上限
idx2Alphabet(256) -> IV 'Excel 2003 形式の上限


これの逆関数:idx2Alphabet もあります

Public Function alphabet2Idx(ByVal colName As String) As Long
Dim iL As Long: iL = Len(colName)
Dim retVal As Long: retVal = 0
For iL = 1 To iL
retVal = retVal + Idx(Left(Right(colName, iL), 1)) * 26 ^ (iL - 1)
Next
alphabet2Idx = retVal
End Function
Private Function Idx(ByVal alphabet As String) As Long
Idx = Asc(UCase(alphabet)) - Asc("A") + 1
End Function



つまり alphabet2Idx(idx2Alphabet(x)) = x が 成り立ちます。
逆関数のほうがすごくシンプルなので idx2Alphabet のほうだってもっとシンプルにできそうだけどこれで卒業とします。

2016年02月28日

「EXCEL VBA] 隠しきれたと思っていたがひょっこり現れた関数名の一覧を念入りにもう一回隠す方法

エクセルVBAでマクロをどんどん作るようになると、以下のように「マクロ」の一覧にたくさん出てきてこれはうざい、何とかせねば、となるのが最初の壁でしょう。

macro2016-02-28_221326.png

これは比較的簡単で、Public Sub *** な関数がここに列挙されます。
なので、Public Function *** にしてしまえばいいのです、乱暴ですが。その際、Fuctionの流儀にしたがって戻り値を定義したりする必要は一切ありません。
もしくは Publicである必要がなければ Private Sub *** にしてしまうのもOKです。

され、これで 上記の図のように マクロの中のすべての関数を隠ぺいできた気になっていました。
ところが最近気が付いたのは、マクロを別ブックにしてさらにアドオン化した後で実は ユーザー定義関数の一覧にすべてのPublic 関数が表示されてしまっていたのです!!これはいかん。遺憾。
2016-02-28_222324.png

ググってみたところ以下の記事を発見。
vba - How can I hide Protected Excel AddIn Functions from Appearing in Insert Function Dialogue Box? - Stack Overflow
対処方法はとても簡単で Option Private Module の宣言を各モジュールに追加するだけ。

実際にやってみたところEXCEL2000からでもこれが有効であることを確認できた。

Javaをチラ見する - きしだのはてな

VBA応用(マクロの起動にプロシージャ名を表示させなくする。)
ここにうまくまとまってます。

2016年02月12日

Windows 10で Shell_NotifyIcon Lib "Shell32" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean が動作しない問題は今は治っているようだ

Windows10でバルーンチップが表示されない ってのは周知の事実だということはわかった。: NN Space BLOG-NN空間ブログ

ふと過去の自分の記事を見返していて、これって今どうなんだろうって やってみたら
以下のように右下から出てきた。この前は何も出てこなかったから最新のWindows10では改修がなされているということだ。
trayi2016-02-12_223030.png

しかしながら違和感がある。これは通知は右から出てくるような流儀に変わったのだろうか?
Shell_NotifyIcon は、システムの常駐アイコン(システムトレイ)の場所からバルーンチップで出てくるのが慣習だったはずだが、タスクバーを左に縦置きしたとしても Shell_NotifyIcon のメッセージは右下から出現してくる。はっきり言って予想外の位置からのメッセージは認識しづらい。

プログラムで特別な対応をしなくてもメッセージが出てくるように治っていることについてはまあ良しとするけれども出てくる場所がそこかいな。

VBAの「参照設定」で同じGUIDだったら、パスが違ってても それらの環境違いで同じブックを利用可能かもしれない!

[EXCEL VBA] .QueryTables.Add のオブジェクトのTextFilePlatform プロパティについて: NN Space BLOG-NN空間ブログ

↑この前の こちらの記事では
MSCOMCTL.OCX の参照先が、
C:\Windows\SysWOW64\MSCOMCTL.OCX
↑ 64BitWIndowsに32bit EXCEL の場合

C:\Windows\System32\MSCOMCTL.OCX
↑ 32ビット Windows に 入れたエクセルの場合

と異なるので 64Bit Windows + 32Bit Excel の環境で作った 参照設定を持っているファイルは 後者の環境では 読み込みエラーになるという結論にしていましたが、あれからいろいろ試した結果 どちらも同じブックで参照エラーなしで行けることが分かりました。

それは、AddFromGuid(sGUID, vMajor, vMinor) メソッドを使う方法です(たぶん)
Excel VBA を学ぶなら moug モーグ | 即効テクニック | 参照設定を自動的に行う
こちらで自動的に(手作業ではなく プログラムで)ブックに参照設定を追加する方法が紹介されています。
この方法を使うと自分の検証した環境ではさらに自動的に、環境違い(参照先のOCXのパスが異なる)でも参照エラーにならずにマクロが使えることが分かりました。
これが成立する前提条件はあまり多くを確かめていませんがおそらくは、各システムに登録されたOCXは同じMajor,Minorバージョンを持っているほうがより動作しやすいだろうなとは考えられます。

Excel VBA を学ぶなら moug モーグ | 即効テクニック | タイプライブラリのGUIDやバージョンを取得する

2016年01月25日

C#もVB.netもアセンブリーを作ってしまえば同じもの

やっぱりC#の方がいいの?VB.NETとC#の勉強環境から案件状況まで | ポテパンフリーランス

VB.netでクラスライブラリを作って C# で参照とか。

最近は 参照設定なしでアセンブリをロードして リフレクションでメソッドを呼び出すのが便利とか思っている。

2015年11月03日

Visual Studio Community 2015 も引き続き無料(非・エンタープライズ用途の場合)なのね

Download Microsoft Visual Studio Community 2015 from Official Microsoft Download Center

Visual Studio 2015 製品の概要

というわけで自宅のPCに入れました。

すると、以前入れていたVS2013 と共存しました。容量くうなぁ。



2015年10月30日

Windows10でバルーンチップが表示されない ってのは周知の事実だということはわかった。

Windows10でバルーンチップが表示されない

自作プログラムでも、バルーンチップが何も表示されなくなって調べたけど解決策はないのか?


Basic use of Shell_NotifyIcon in Win32 - CodeProject

TETSUCOM 現代のIT開発雑記: VBAからシステムアイコントレイを使う

2015年10月28日

EXCEL VBA で「真のグローバル変数(long型に限る)」を使う

Truly Global Variables With SetGetProp
↑ここにすべて書いてあります。サンプルのソースコードから必要なところだけコピーして自前のマクロに取り込みました。

エクセルが起動している間ずっと変数を保持してくれる。それが 真のグローバル変数だとしましょう。
記事にも書いてありますが、モジュールに Publicの代わりにGlobalと記述して得られるグローバル変数は確かに、ブック(プロジェクト)をまたいで エクセル起動中共通で使える変数なんです(ScopeはGlobal)。
でもその変数を定義しているブックを閉じたり、開きなおすと 初期化されてしまいます。真のグローバルじゃない!(Life Time は Globaじゃない!)

Excelプロセスが起動中はずっと保持し続けるような真のグローバル変数はエクセルが持つべきなのです。( レジストリーでもいいじゃないかという話はちょっと違うので今回はしません)。

エクセルが起動したら初期化し、あとは何度ブックを開こうが閉じようが 共通の変数を参照する。
そのために上の記事が言っていることは、プロセス(エクセル)のプロパティへ値を突っ込め!ということです。ただしLONG型の数値しか保持できませんが。

とりあえず、習作として コピーしたロジックをもとに 同じブックを開いた時にエクセルに追加したカウンター用プロパティへ ブックを開くたびにインクリメントして、特定の同じファイルを開いたらそれを何度開いたかを表示する仕組みにしてみました。
これの使いどころは常駐させているエクセルマクロが「リロード」されるようなシチュエーションを検知できるってことです。通常めったにないことですが やろうと思ったらリロードさせることは簡単でした。この機能が有効に働いていることも確認できました。

めでたし、めでたし。

上の記事の説明していることはエクセルに限らない(ウィンドウハンドルを持っているプロセス全般について同じ)なので 起動中のプロセスに 何らかのタグ付けをしてLONG型の値を持たせることもそれを変更することも可能なわけです。
発想を変えると、プロパティ名称そのものをString型のValueだとみなせば 文字列の値もプロセスに付与できるってことです(よね?)。

検証(からそのまま実装)完了。

・・・ていう感じで日々、マクロに機能が追加されていくのであります。
10年前くらいから作り始めたツールを今も拡張を続けている: NN Space BLOG-NN空間ブログ

2015年10月06日

10年前くらいから作り始めたツールを今も拡張を続けている

基本的にマイクロソフトプラットフォームばかりだが・・・

1.エクセルのマクロメニューツール(日々拡張) 'VBA/Win32API

2.連続圧縮ツール(ほぼ更新なし、決定盤)'WSH/VBS(これだけは当ブログで公開しています)

3.DB閲覧、テーブル操作スクリプト自動生成などなど多機能ツール 'VB.net/framework 2.0,4.0両対応


自分の作業効率をアップさせ、ストレスを減らすこれらのツールはなくてはならないものとなっている。

Java(Script)系が弱いので、もっとそれらを活用したツールを作りたいと思っている。つかず離れずでやってます。

2015年10月05日

7-Zip 15.08 beta で Linux ファイルシステム[ext3/ext4]・イメージ・ファイルの展開に対応。 いったいどこまで進化するのか 7-zip

7-Zip / Discussion / Open Discussion:7-Zip 15.08 beta

早くベータが取れてほしい。そうしたら社内できっと使えるようになる。

2015年09月26日

エクセルのバグをまたしても発見してしまった(サーバー共有フォルダ内のファイルの埋め込み時のファイル名化け問題)

Excel2010,2013どちらも発生。
対象ファイルは テキストファイル .txt など。 エクセルファイル .xls は化けない。

・手順(条件)

挿入>オブジェクト>ファイルから:アイコン表示
2015-09-26_020415.png
という設定で、ネットワーク共有データを埋め込みし、「ファイル保存」する。

すると、保存後のタイミングで埋め込んだファイル名が化ける。
2015-09-26_020315.png
手元で確認した .txt / .zip / .jpg は化けた。 .pdf / .xls は化けなかった。 いったいどういう理屈だ。

この埋め込み元のファイルをデスクトップなどにコピーしてから同様に埋め込み・ファイル保存を行うと今度は化けない。

2015年09月23日

思えばEPPLUSには助けられたなー

EPPlusとNPOIで使い分けをするようになってきた: NN Space BLOG-NN空間ブログ

以前プロジェクト開始前に、適当に見繕ったのがEPPLUSだった。その時はいろんな問題が出るとは思わずこれでいけるやろと軽く考えていた。

しかしプロジェクトでEPPLUSを使いだしていろいろテストしていくうちにこれじゃああかん(エクセルファイルが壊れてしまう)という事象にたくさんぶち当たり、EPPLUSフォーラムにもたくさん投稿した。
そんなこんなでバージョン4.0がリリースされた後も何度かバージョンアップして今の4.04になったあたりでプロジェクトも無事に収束し これじゃあアカンと思っていたバグも修正されてそこそこ使えるライブラリーになったEPPLUS.
そこから全くバージョンアップの雰囲気がない。まるで自分のプロジェクトに合わせていろいろバージョンアップしたかのような動きとも思える。今となっては。

ただEPPLUSは .net Framework 2.0 では動かないので、素のWindows7 を前提にした環境では EPPLUS の動作を推奨しにくい。
そこはマア諦めているので そういうところには NPOIを使う。 これも 幾分バージョンアップしてそこそこの ものになっている。使い込んでみると設計思想も見えてきて使いこなすことができそうに思えてきた。しかし使いやすいライブラリではない、NPOI.

2015年09月17日

PDFの構造を理解して自前でPDFを生成する

詳細PDF入門 ー 実装して学ぼう!PDFファイルの構造とその書き方読み方 - プログラムモグモグ

なんかすごく面白そう。

2015年09月04日

EPPlusとNPOIで使い分けをするようになってきた

NPOIもEPPLUSもClosedXMLもなんかいまいち。: NN Space BLOG-NN空間ブログ ←と思っていたのが1年以上前。あれから NPOIも EPPLUS も程よく進化しました。

.net Framework 2.0 しか使えない環境(4.0以上に上げずらい環境)もしくは *.xls ファイルを使うように強制されている ・・・ NPOI を使う。

・.net Framework 4.0 以上が使える環境もしくは *.xlsx を使うことに支障がない状況 EPPLUS を使う。

プログラミングしていてストレスの無い設計思想だと思うのは EPPLUS 。

最近NPOIの NPOI 2.2.0 というアルファー版が出た。 読み込みだけなら *.xlsx もイケるそうだが 試していない。

それぞれどちらかの環境に限定できればどちらを選んでも支障はない。
xlsx 読み込んで xls に変換したいとかその逆がしたいとか そういうことは避けて通るしかないけども。ちゅーか、そういうのはEXCELでやって。

2015年08月25日

いまさらになってみたことのないEXCEL VBAでのエラーメッセージをたくさん見るようになった

関数またはインターフェイスが予約されているか、または Visual Basic でサポートされていないオートメーション タイプが関数で使用されています。
関数またはインターフェイスが予約されているか、または Visual Basic でサポートされていないオートメーション タイプが関数で使用されています。 - Google 検索


現在アンロードできません
現在アンロードできません - Google 検索

微調整していくうちにバランスがどんどん変わっていく・・・・

制御不能だ、これ。しかもPCごとに挙動が違うからあっちを直すとこっちがおかしくなるみたいなことが多発。困り果てる。

2015年08月24日

Excel VBA : ActiveSheet オブジェクトがなぜ WorkSheet 型じゃなくて Object型なのかが分かった気がするよ、、、

今まで気が付かないでいたというのも幸せだったのかもしれないが、
・ワークシート
の位置に
・グラフ
を置くこともできます。
グラフのほうは WorkSheet ではなくて、 Chart オブジェクトです。

つまりEXCEL VBAがマクロで動作する環境の中では ActiveSheet は この両方のオブジェクトを格納できる必要があるのでOBject 型変数になっています。・・・という理解にようやく本日たどり着きました。

ActiveCell は Range だし、 ActiveChart はもちろん Chart ActiveWindow が Window 型で
ActiveWorkbook は Workbook 型。
それなのに、結構使う WorkSheet については ActiveSheet オブジェクトの型は 不定のObject型。
何とかならなかったのかねぇ・・・・

もっと早くに気が付いていたかった!


2015年08月23日

EXCEL VBA : UserForm の ウィンドウハンドル: hWnd の安全確実な求め方

EXCEL VBA で UserFormを扱うときに困るのが、Formのプロパティに ウィンドウハンドルが無い、ということです。
それを自前で備えてしまいましょうという方針なのが以下の記事。素晴らしい。

VBAでUserFormのウィンドウハンドルを取得する方法

・以下を定義部に宣言
Private Declare Function WindowFromAccessibleObject Lib "oleacc.dll" _
(ByVal IAcessible As Object, ByRef HWND As Long) As Long

・以下をそれぞれのUserFormの中に記述。
Public Property Get hWnd() As Long
WindowFromAccessibleObject Me, hWnd
End Property


Windows9x系では使えないそうですが、今更のことなので無視できます。
GetActiveWindow とか、FindWindow とか を使うと一抹の不安がありますが上記方法は確実です。

MySQL 5.7の罠

MySQL 5.7の罠があなたを狙っている

たぶん社内で使っているのは5.6だろうから次回気を付けます。

なにこれ不思議。無重力状態でT字ハンドルを回し外すと起きる現象
予想外のT字ハンドルの動きに驚きを隠さなかった。
みんなのコメントにある地磁気回転もきっとこんな風にして起きるんだろうなというのも同意。(実際には違う理屈だと思うが)。
タグ:わなわな

2015年08月19日

GUIアプリで、コンソールにメッセージを書く 〜 ほぼ9年越しに解決策を見出した

ウィンドウズアプリで標準出力ログをテキストに書く: NN Space BLOG-NN空間ブログ
↑9年前、
・コンソールアプリ(のコンパイル)だと、コンソールに文字を出せるがコンソールウィンドウが出ちゃう
・ウィンドウズアプリ(のコンパイル)だと、コンソールに文字が出せない。でもリダイレクトでファイルには出力できる。

そういう結論だった。

しかし以下の記事を見つけてようやく考えを改めた
VB.NETで、Console-Window Hybrid Applicationを作る。: Windows Script Programming
↑今から5年間の記事

・ウィンドウズFormアプリ(のビルドを)をやめて、コンソールアプリビルドとしてWindowsフォームアプリケーションを作成する
・リンク先の記事のように エクスプローラから直接起動された場合には、コンソールウィンドウを非表示にし、コマンドプロンプトなどから起動された場合にはそのままにしておくことで コンソールへ文字の表示が可能。

素晴らしい。

2015年08月17日

7-Zip 15.06 beta was released.

7-Zip / Discussion / Open Discussion:7-Zip 15.06 beta

もうそろそろかなぁ。正式版リリース。

2015年08月16日

EXCEL VBA: Range("A1") の 省略記法として [A1] という書き方があることを初めて知った

Dim r As Object
Set r = [A1] ' = Range("A1") と同等

[A1:C3] などもかける。
まあ、親オブジェクトをはっきりさせた書き方ではないので一時的にタイプ数を節約したいときくらいしか役に立たないだろうけど。

似たような書き方で、定数で初期化した配列も作成できるということも同時に知った。
Dim arr As Variant
arr = [{2,4,6,7}] 'Variant(1 to 4) に 初期値を代入したものと同じ
arr = [{"2",4}] '"文字列", 数字 混在配列も可能(変数がVariant型なので)

2015年08月12日

EXCEL NPOI の GetFormat のパラメータに設定可能なフォーマット文字列は Excel VBAでいうところの NumberFormat であって NumberFormatLocal じゃなかったという件と書式文字列についてわかったことをだらだらとまとめてみた

NumberFormatLocalとNumberFormatの違い:エクセルマクロ・Excel VBAの使い方

VBAで数値の書式設定を行うNumberFormatLocalプロパティ ってものがあるんですが、これ 見たことがある人はいると思いますが以下の設定です。
nf2015-08-12_223449.png

セルにはそれぞれ
123456
-1236456
0
と記入し、以下の書式文字列を設定すると 上記のように表示されます。
\#,##0_);[赤](\#,##0);"ゼロ"

書式文字列が長くなると、もはや手に負えなかったのですが 最近分かったのは書式文字列は
プラスの数値の書式;マイナスの数値の書式;ゼロの書式
という風にセミコロンで区切って最大3つ書けます。
つまり 上記例でいうと
123456 → プラスの書式 → \#,##0_) → \123,456
-1236456 → マイナス書式 → [赤](\#,##0) → (\ 1,236,456)
0 → ゼロ書式 → "ゼロ" → ゼロ

まずマイナスの書式から分析すると、
・赤字で
・3桁区切りで
・先頭に¥記号を付けて
・数値の両側を()で囲う
という書式です。

次にプラスの書式
・3桁区切りで
・先頭に¥記号を付けて
・マイナスの時につけた 閉じかっこ)の分 の位置をずらすために 閉じかっこ分の位置を空白に

最後にゼロの書式
これ、無くてもいのですが たとえば固定文字列の ”ゼロ” と書けば その文字がそのまま表示されます。

この辺のことを最近ようやく知ってエクセルすげーと思うようになりました。いまさらですが。


閑話休題。

というように書式はVBAでみるとNumberFormatというプロパティに格納されています。
最近NPOIも使ってエクセルファイルを作っていますが 書式設定にもこだわるようになった結果、いったいどんな書式を設定すれば思い通りになるのかをわかりあぐねていたところ
こういうライブラリーは英語圏のソフトウェアなのでNumberFormatLocalではなく NumberFormat の値をまねすればよい結果になるというところまでわかってきました。これらのプロパティは片方に突っ込めばもう片方は自動評価されるようです。
なので英語版で作って日本語の書式を気にする必要もないということです。

つまり、
range("G14:G16").NumberFormatLocal で得られる \#,##0_);[赤](\ #,##0);"ゼロ" という文字じゃなく

range("G14:G16").NumberFormat で得られる $#,##0_);[Red]($ #,##0);"ゼロ" がいいということです。特に色の指定については。
そこで NPOI で .GetFormat( "$#,##0_);[Red]($ #,##0);""ゼロ""" ) するわけですが どうしたことか
作ったファイルを実際に開くと通貨記号が $ のまま表示されます。色も出ない。
これはおそらく EXCEL VBA では勝手に色指定や通貨記号の変換を NumberFormat と NumberFormatLocal の間でやっているのでしょうね。
対してNPOIでは正しいものを設定しないといけないわけか。

結局 NPOI では \#,##0_);[赤](\ #,##0);"ゼロ" を実現するために
.GetFormat( """\""#,##0_);[Color3](""\"" #,##0);""ゼロ""" ) としました。
これをNPOIで設定したセルの書式をエクセルにて 見直すと [Color3]が[色3] に置き換わって見えます。ここらあたりがEXCELのローカライズの凄さかな(ローカライズが微妙なところはいくつもあるけどそれはさておき)。


本の虫: Lenovoのファームウェアがファイルシステムを改ざんするクソ仕様なので絶対に使ってはいけない
→HDDを暗号化していればBIOSからそんな真似はできないね。


そして、書式設定をもっと詳しく掘り下げたい場合はこちらがお勧め
Custom Number Formats, Date & Time Formats in Excel & VBA; NumberFormat property
ココを見て初めて知ったのが Number Scaling の コンマ, の役割。
書式の最後に,を重ねることによって1000単位で割り算した結果を表示してくれる。
123456という数字に 0, という書式を付けると 123 と表示される。0.####,, だと 0.1235 と表示される。

さらに / (分数書式)
0.5 という数字に #/# という書式を付けると 1/2 (最も近い分数 、この場合ジャストの分数) で表示される。

セルに文字を充填する*【アスタリスク】
これは正直使いどころが分からないが 0.5 という数値に 0.0*= という初期を付けると 0.5======= とセル幅いっぱいに = が充填される。

4番目の書式は文字列だった!
サイトからの抜粋になるけども以下のようにすると
"[Blue]#,###.00; [Red](0.0#); [Green]0.00; [Magenta]@"
文字列はマゼンタ色(Magenta)で表示される。

これらはあくまでも数値そのものをいじらずにセル上での表示の方法だけを制御しているってこと。
ここまでできると、「条件付き書式」でなくても簡単な色付け、書式わけができてしまうね・・・・

表示書式が微妙に高機能なせいで条件付き書式でできるところもカバーしてしまいどっちで設定するのがいいのか悩ましい場面もありますが知っておいて損はないでしょう。

2015年07月21日

イメージ通りのプログラミングができるころには陳腐化していることもある

イメージ通りのプログラミングができるようになるまでにはけっこう時間がかかる - shi3zの長文日記

なんだかんだで、入社以来VB(S|A|.net)?,C#,Java(Script)あたりをメイン言語にして10年以上たつ。

その昔はC(++), Fortran とか。

JavaScript - クラスの落とし穴1 - プロパティの初期化 - Qiita

JavaScript - クラスの落とし穴2 - メソッドとクロージャ - Qiita

2015年05月11日

まだJavaScriptのことがよくわかっていないが、わかった気がする

(function(){
var nums = "りんご,ミカン,ダイコン";
var numAry = nums.split(",");
for (var i in numAry){ alert(i); }
})();
 ↑これで、いったい何が alertで表示されるでしょうか。
正解はここをクリック(3回OKボタンを押してください)

そこで以下のように書き換えると、ようやく思った通りになった。
(function(){
var nums = "りんご,ミカン,ダイコン";
var numAry = nums.split(",");
for (var i in numAry){ alert(numAry[i]); }
})();

正解はここをクリック(3回OKボタンを押してください)

・JavaScriptは何でも連想配列
・連想配列のキーになるシンボルのことをプロパティという
・for in はオブジェクトのプロパティを走査する記法
JavaScript の配列と連想配列の違い - IT戦記

オブジェクトにはプロパティをあとからでも、あらかじめでも付け加え放題。

JavaScript - for in文とfor文  - Qiita

実用的?変態的!?JavaScriptの実用的なショートコーディングをまとめてみた: がおさんち 技術部屋

変態すぎるJavaScriptコード・・・ | IDEA*IDEA
↑Worldっていうリンクをクリックすると動きます。すげえ、JavaScriptのフラクタル構造といっていいのか。

JavaScript - for-inとObject.keysの違いを正しく知る - Qiita


雨にも負けず 風にも負けず 雪にも夏の暑さにも負けぬ 丈夫な体を持ち 欲... : 2ch 思わず笑う 秀逸なコピペ 集(急)【※周りに人がいないことを確認!】 - NAVER まとめ

雨にも負けず
風にも負けず
雪にも夏の暑さにも負けぬ
丈夫な体を持ち
欲は無く
決して怒らず
いつも静かに笑っている


そういう人に
仕事丸投げして帰りたい

2015年04月06日

NT Coreさんの CFF Explorer(Exe ファイルのPEヘッダとかを見たり)のツールがすごい

NTCore's Homepage

こういうのって有料なものが多いですが、無料です。

そして管理者権限を必要としませんので、使いやすいです。

しかもこれ、.net の EXEにも対応しているという優れもの。

何も考えずにExeを解析できます。

ほかにも関連ツールだと
PE Tools | SourceForge.net
こんなのとか PE Explorer: EXE File Editor, Resource Editor, DLL View Scan Tool, Disassembler. こんなのが見つかりましたがあんまり試しておりません。


NTCore CFF Explorer が もっともベストな PE header editorであると、このスレッドで語っているのを信用しました。
c - Tools to read PE headers for binaries - Stack Overflow

自分でも最近になって、EXEのビルド日をファイルのタイムスタンプからではなくてPEヘッダから取り出して表示するプログラムを作ってみたんだけど、どうも時差があるみたい。(エクスプローラの表示とずれることがある)。でも、これって内部のPEヘッダ情報が正しくて ファイルのタイムスタンプのほうが間違っているんだろうなと思う。そして、極めつけはどんなに古いEXEでもタイムスタンプを更新してしまえば新しく見えてしまうということ。
最近XMLファイルを変換するのに MSXSL.exeを使うんだけど、こいつが古かったので新しいのがほしかったからいろいろ検索するんだけども見つかるのはやっぱり古い。ダウンロードしてみてファイルのタイムスタンプを見てここ数年の日付が付いていてももっと古い時のファイルのSHA-1とかと同じ、つまり同じファイル。
そこでこのプログラムでビルド日を見たらどれもすべてが2001年の8月だったりして、ああ、これが本当の作成日なんだなと(時差があっても1日違うくらいのものなので気にしない)

たとえばこういうところにいまだに公開されているMSXSL.exeの最新版をゲットしてきたとします。
Download Command Line Transformation Utility (msxsl.exe) from Official Microsoft Download Center
+Detailsを開くと以下のことが書いてあります。
Version:2.0
File Name:msxsl.exe
Date Published:9/19/2004
これを見ると、2004年にリリースされているように見えますね。

でもですね、このファイルのデジタル署名のプロパティを見ると
‎2001‎年‎9‎月‎14‎日 4:07:28
と書いてあるので実際はこれより古い時期に作成されているわけなんです。

そこで、自作のPEヘッダからのビルド時刻の取得ツールをかますと
2001/08/29 05:33:13
という日時が出てきます。

つまりこれがそのEXEファイルを作った日。 これ以上さかのぼって古いものは出てこないし、どんだけ新しいタイムスタンプを持っていてもこの日が一緒なら(またはハッシュが一緒なら)、おんなじファイルってことです。

結論を言うと XSLT変換のためのツール MSXSL.exe は もう14年近くもそのままの状態で使い続けているということです。
まあ、実際には参照する先のDLLとかで動きが変わっていくためにこのようなEXEは長寿命でいられるということの証なんだと思いますが。

そして、NTCore's Homepage index のほかのアイテムを見ても(名前からして)面白そうなツールをいろいろ見つけて非常に楽しいです。

ツールのみならずこの方いろいろな記事を書いておられるので、また読んでみたいです。
NTCore's Homepage articles
ブログの更新は2年前に止まっていますがこの状態でまだ参照できるうちに見ておくべき素晴らしい記事だと直感します。

・おすすめ楽天ショップ1:trendyimpact楽天市場店
・おすすめサプリショップ:iHerb.com
・おすすめ楽天ショップ2:上海問屋
Powered by さくらのブログ