ほっとひといき給湯室

ほっとひといき給湯室の掲示板です。お気軽にどうぞ!
  • 掲示板への投稿には会員登録(無料)が必要です。会員登録がまだの方はこちら
  • 掲示板ご利用上のお願い」に反するご記入はご遠慮ください。
  • Q&A掲示板の使い方はこちらをご覧ください
トピックに返信
質問

 
技術系雑談スレッド7
投稿日時: 15/05/28 06:09:34
投稿者: kumatti
投稿者のウェブサイトに移動

※ 技術系と断っていますが、特にカテゴリーを定めていません。
 
前スレ
 
技術系雑談スレッド6
http://www.moug.net/faq/viewtopic.php?t=69505

投稿日時: 15/06/04 06:41:47
投稿者: kumatti
投稿者のウェブサイトに移動

 
・VBAでの演算子やステートメントのフック
 
(実装面での)Unicodeに非対応や機能が脆弱であるとか、処理速度が遅い事に対する改善として
ソース側に手を入れるのではなくて、表題通りにフックして、そのフックプロシージャで実装しようと言う試みです。
 
ただ、DLLのバージョンが変更されるなどして関数アドレスが一意である事は担保されませんので、
汎用性はさほど期待出来ません。
また、内部関数の方になりますので引数が逆順になるとか、
引数の個数が増えるとか、ポインタ渡しになるとか、弱参照になるなど、扱いは一層難しくなります。
 
あくまで、こういうテクニックもあると言うご紹介までに留めておきます。
 
ーーー
・&演算子のフック
 
さっそく、注意点がありますが、フックプロシージャで&演算子を用いると  無限再帰  になりますので
注意が必要です。
戻り値を返すのでプロシージャの呼び出し側で、弱参照を処理する必要があります。
https://gist.github.com/kumatti1/53585db6f6a79d53680a
 
 
・Midステートメントのフック
 
引数で参照を返してますので、呼び出される側(フックプロシージャ)でも
呼び出し側でも弱参照を処理出来ます。
https://gist.github.com/kumatti1/dfb89c52cd870f25a438
 
ーーー
VBA関数の方はIATのAPIフックとなり、既に手法は確立してますし、汎用性も十二分にあります。

回答
投稿日時: 15/06/04 07:54:00
投稿者: daive

>(実装面での)Unicodeに非対応や機能が脆弱であるとか、処理速度が遅い事に対する改善として
>ソース側に手を入れるのではなくて、表題通りにフックして、
>そのフックプロシージャで実装しようと言う試みです。
一般の方、解っていない方は、この認識で行うと、火傷しますので、
フック系は扱わない方が無難です。
本質的に、他に代替え手段が無い場合のみに、適用する事柄です。
 
私の場合の、プローチとしては、
1.どこが遅いのか、何が遅いのか、なぜ遅いのかを
  計測、検査、原因究明をする。
2.アルゴリズムでの改善の可能性を探る。
3.ハードウェア面での手当が出来ないか、検討する。
  PCが遅いのであれば、改善方法が無いかなど。
 (RAM2Gで遅いなどと言っている場合は、RAM増設)
  ディスクの読書が遅いのであれば、
  SSD化して改善の可能性が無いかなど、
4.VBAで組んでいるのであれば、
  いっそ言語を、VS20XXに変える。
  INTEL C/C++に変える。
 (アプリケーションフックを使うより、現実的)
 
種々検討して、どうしても方法が無い場合のみ
暫定対応として、アプリケーションフックを使うべきです。
恒久的対応となりえないのは、先にかかれています。

投稿日時: 15/06/08 06:43:54
投稿者: kumatti
投稿者のウェブサイトに移動

https://twitter.com/igeta/status/606611110465126400
Twitterで話題に挙がってた変数の宣言と同時にNewで参照をセットする際の挙動に付きまして興趣(きょうしゅ)を感じたもので、
IEで試したところ、別のインスタンスが割り当てられるもののNothingのセットが有効に働かない誠に稀有な例ですね( ̄□ ̄;)!!

Option Explicit

Sub hoge()

    Dim ie As New InternetExplorer
    ie.Visible = True
    Set ie = Nothing
    ie.Visible = True

End Sub
    
Sub hoge2()

    Dim ie As InternetExplorer
    Set ie = New InternetExplorer
    ie.Visible = True
    Set ie = Nothing
    ie.Visible = True

End Sub

投稿日時: 15/06/20 06:37:01
投稿者: kumatti
投稿者のウェブサイトに移動

・DispCallFuncの仕様が変わった件
 
多分、Win8.1からだと思いますが、ParamArrayやArrayでのVariant型の配列に非対応になった模様です。
なので要素が配列のVariant型にコピーする事になるのですが、内部処理形式をLong型と決め打ちして(CLngでキャスト)、
対応する事になりそうです。
 
※APIだとVariantToInt32辺りか。
https://msdn.microsoft.com/en-us/library/windows/desktop/bb776608%28v=vs.85%29.aspx

回答
投稿日時: 15/06/21 16:30:57
投稿者: yayadon

仕様の件はよくわかりませんが,
CLngしないといけない件は,
Dim Vnt でなく
Dim Vnt() As Variant
ですね。
 

投稿日時: 15/06/21 17:43:46
投稿者: kumatti
投稿者のウェブサイトに移動

yayadonさん、ご教示ありがとうございます。(`・ω・´)ゞ
バッチリですv(´∀`*v)ピース

回答
投稿日時: 15/06/23 10:07:56
投稿者: kanabun

kumatti さん、スレッドお借りして質問させて下さい m(_ _)m
 
別板(OfficeTanaka)であった質問なのですが、
「読み取り専用でファイルが開きません」

引用:
ファイル名に"一覧"が含まれるExcelファイルをフィルタリングし、読み取り専用で開きたいです。
Application.Dialogs(xlDialogOpen).Show Arg1:="*一覧*.xls*", Arg3:=True
 
実行すると、ファイルを開くダイアログにフィルタリングをかけることはできているのですが、
選択したファイルが読み取り専用になりません。
何か誤っているのでしょうか?(Excel2010)

ということなのですが、こちらのPCで確認してみると、
 Excel2002    成功
 Excel2003    成功
 Excel2007    失敗
 Excel2010    失敗
という結果になるのですが、なぜそうなるのか
理由が分りません。(こちらOSは Windows7Pro です)
何か 設定とかあるのでしょうか?
 
というのが質問です。Excel板で質問しようかとも思いましたが、
何かマルチでミイラ取りになる(あっちで回答者やってこっちで質問者やる)
のも気が引けたので、
給湯室でそっとお伺いします。スレッドの趣旨にそわなくてすみませんが、
よろしくお願いします。
(これからでかけます。次アクセスできるのは 明日よるになります m(_ _)m)

回答
投稿日時: 15/06/28 08:25:52
投稿者: kanabun

引用:
 Excel2002    成功
 Excel2003    成功
 Excel2007    失敗
 Excel2010    失敗
という結果になるのですが、なぜそうなるのか
理由が分りません。(こちらOSは Windows7Pro です)
何か 設定とかあるのでしょうか?

元スレで WinArrowさんが
> Excel2007バージョン以降は、機能しなくなった・・・バグの可能性あり。
とコメントされていますが、
設定とかで対処できることではなく、やはり Excel2007 にするとき、
スイッチを戻し忘れたような...そういうことなんでしょうかね?

回答
投稿日時: 15/06/29 14:35:30
投稿者: kuni0416

こんんちは。
海外でも2007年に同様の質問が出ていたようです。
http://www.pcreview.co.uk/threads/xldialogopen-arguments.3331383/
helpの記載が間違っているようにかかれてますね。
2007以降で使用できないならバージョンによる差異と思うしかないですかね。
 

引用:

The help files for Excel (and all of Office) have gotten continuously worse
since about Office 97; Jim's comment indicates that this topic hasn't been
updated since Excel 95. The help examples are poorly written and do not
often illustrate more than a rehashing of the syntax. When they are more
illustrative, like this example, they are incorrect. This is unfortunate.
- Jon
Jon Peltier, Microsoft Excel MVP
Tutorials and Custom Solutions
Peltier Technical Services, Inc. - http://PeltierTech.com

回答
投稿日時: 15/06/30 10:36:31
投稿者: kanabun

kuni0416 さんの引用:
こんんちは。
海外でも2007年に同様の質問が出ていたようです。
http://www.pcreview.co.uk/threads/xldialogopen-arguments.3331383/
helpの記載が間違っているようにかかれてますね。
2007以降で使用できないならバージョンによる差異と思うしかないですかね。
おっしゃるとおりかなと思います。
 
kuni0416 さんが紹介された質問スレッドは興味深い内容なのですが、
英語なので、ニュアンスを理解できなくて、推測でのコメントになりますが、
 
質問者さんが
 
Application.Dialogs.Item(xlDialogOpen).Show Arg1:="Book1.xlsm", Arg3:=True
 
という構文は
> MS Press book on Programming Excel 2003
に載っていて、それどころか、Excel2007 のヘルプにもちゃんと書いてある。
http://msdn2.microsoft.com/en-us/library/bb236937.aspx
 
その通り記述して 開いたBookが Read-Only にならないのはどうしてでしょう?
という質問だと思うのですが、そこでのレスは
パラメータ(の位置)が間違ってないか?とか、
ヘルプがアップデートされていない、
自分は Dialogs.Item(xlDialogOpen)は使っていない(GetOpenFilename や
Application.FileDialog(msoFileDialogOpen) を推奨)
とか...と...
何だかはぐらかされている印象を受けるんですよね(-_-)
 
まぁ、ヘルプが古いバージョンの使いまわしなのはぼくら全員が先刻承知して
いることで、Find,FindNext メソッドのバグつき使用例とか、全然改正されて
ませんよね!?
ただ、この問題は、たとえば、Application.FileSearchメソッドが 2007 で
外されたというたぶん2007設計者の意識的改変とちがって、偶発的な 失効
のような雰囲気が漂っています。近い例を挙げると、図形の、それが乗っかっ
ている左上セル を取得する TopLeftCellプロパティが、それまで「セル」を
返していたのに、あるバージョンから「行」を返すようになった。そのため
TopLeftCellとBottomRightプロパティを用いて図形がいくつのセルのうえに
乗っかっているか Countプロパティのまえに .Cells プロパティをつけないと
行数を返すため、正しくカウントできなくなった。...ことと似ていると思い
ます。
Excel2013 でさえ、
Built-In Dialog Box Argument Lists
https://msdn.microsoft.com/en-us/library/office/ff838781.aspx
をみれば、相も変わらず
Applies to: Excel 2013 | Office 2013 | VBA

xlDialogOpen  Argument list(s)
file_text, update_links, read_only, format, prot_pwd, write_res_pwd, ignore_rorec, file_origin, custom_delimit, add_logical, editable, file_access, notify_logical, converter

と載っています。これは仕様(能書き)を説明しているのだから、それでいいの
ではないですか?
問題はこの仕様=ヘルプの記述が、実際には2007から、能書き通りには動かなく
なったということで、その情報が、MSからはもちろんネット上にほとんどない、
ということです。
 
 そんなの、いちいち騒いでいたら、仕様がないじゃん(いえ、しょうがない)
という声が聞こえてきそうです。良識あるプログラマーは「ああ、またか。」
といいながら FileDialogなど、代替メソッドに切り替えていくのでしょうね。

回答
投稿日時: 15/06/30 14:52:47
投稿者: kuni0416

こんにちは。
日本語訳の際に誤って入れているのかと思うと英文でも記述は同じですよね。
Application.Dialogs.Item(xlDialogOpen).Show arg3:=True
Itemを入れても入れなくても2007ではRead-onlyにはならないので、記載通りに書いても正常に動作しない場合は代替えを探すしかないのが現状ではないかと。
ヘルプに対して「役に立ちましたか?」的なものには、誤りではないかと送信していますが、変更される様子はないです。
バージョンアップ時の仕様では抜いていないからそのまま動作するはずとの認識がMS側にあるんですかね。
書籍は、購入したことが無いのですが、VBAに関する一般的な書籍ではなんと書かれているか気になります。
 
お金取って間違ったことを掲載していたら…書籍を購入した人はどこにクレームつけるんだろう。
 

回答
投稿日時: 15/07/01 18:10:08
投稿者: daive

>お金取って間違ったことを掲載していたら…書籍を購入した人はどこにクレームつけるんだろう。
心ある、著者、出版社の場合は、
出版社のホームページから、訂正が閲覧できる場合もあります。
著者のホームページでも、同様の訂正が載る場合もあります。
出版社によっては、クレームさえ受付拒否もありますし、
当該頁の訂正要望メールを送っても、なしのつぶての処もあります。

本に書いてある通りしたら、金銭的損害がでた、
訴えたいという事であれば、
扱う弁護士がいるかどうかから、まずは調べてください。
本に書いてある事を、鵜呑みにして、実行出来ないとか、
損害が出ても、通常は、自己責任です。

技術系図書では、普通に、あたりまえに、間違った事が書かれていますし、
主観の違いによる、意味の取り違えもあります。
時代によって、内容がそぐわなくなっている場合もあります。
⇒一次情報の入手が必要になる事、自分で実証することが必要な事が、
 理解できる方は、技術書を正しく読むことが可能です。
 鵜呑みにするかたは、技術書を読んでも、正しい情報が得られません。

回答
投稿日時: 15/07/02 13:32:08
投稿者: kuni0416

こんにちは。
daiveさん、情報をありがとうございます。
 
kanabunさんの

引用:

別板(OfficeTanaka)であった質問なのですが、
「読み取り専用でファイルが開きません」

とあったので、自分の環境で試しても出来ず、バグ可能性との指摘もありましたのでどこかに何か書いてないかなと検索してみてもバグとも書かれていないし、ヘルプの記載に関する修正もないので、VBAの本を書く人はどう記述しているのかなと気になり、また、本の内容を鵜呑みにするかたの方がクレームをつける率が高い気もして
引用:

お金取って間違ったことを掲載していたら…書籍を購入した人はどこにクレームつけるんだろう。

と書きこんでしまいました。
 
出来ないなら仕方が無いので代替案でとして作るので、自分が何を作るので有ればよいのですが、何故出来ないのかが不明なのでもやっとしているだけで金銭的な実害は有りません。
言語の文法書類でも間違った文例はありますので、またかと思うぐらいです。
ただ個人的には、お金を取って本を売るのであれば内容の検証を著者はしておくべきだと思っています。
 
まとまらなくなりましたが、出来ない理由を知ってすっきりしたいです。

回答
投稿日時: 15/07/02 20:00:51
投稿者: UO3

kanabun さんの引用:
近い例を挙げると、図形の、それが乗っかっ
ている左上セル を取得する TopLeftCellプロパティが、それまで「セル」を
返していたのに、あるバージョンから「行」を返すようになった。

 
えっ! そうだったんですか?
今まで、(結構長い間)全く気にもせずに、「セル」として扱ってきました。
で、心配になって、xl2013ですけど、たった今、検証しましたら、TopLeftCell は
「セル」になっていましたが?

回答
投稿日時: 15/07/03 11:58:54
投稿者: mattuwan44

UO3 さんの引用:
kanabun さんの引用:
近い例を挙げると、図形の、それが乗っかっ
ている左上セル を取得する TopLeftCellプロパティが、それまで「セル」を
返していたのに、あるバージョンから「行」を返すようになった。

 
えっ! そうだったんですか?
今まで、(結構長い間)全く気にもせずに、「セル」として扱ってきました。
で、心配になって、xl2013ですけど、たった今、検証しましたら、TopLeftCell は
「セル」になっていましたが?

2010で試してみました。
 
?activesheet.shapes(1).topleftcell.address
$C$4
 
となりますが、、、「行を返すとは?」

回答
投稿日時: 15/07/03 19:35:28
投稿者: kanabun

mattuwan44 さんの引用:
UO3 さんの引用:
kanabun さんの引用:
近い例を挙げると、図形の、それが乗っかっ
ている左上セル を取得する TopLeftCellプロパティが、それまで「セル」を
返していたのに、あるバージョンから「行」を返すようになった。

 
えっ! そうだったんですか?
今まで、(結構長い間)全く気にもせずに、「セル」として扱ってきました。
で、心配になって、xl2013ですけど、たった今、検証しましたら、TopLeftCell は
「セル」になっていましたが?

2010で試してみました。
 
?activesheet.shapes(1).topleftcell.address
$C$4
 
となりますが、、、「行を返すとは?」

あれ? 即効テクニック研究室で一時大騒ぎしたのに?
ご存知なかった、ですか?(林修ふうに) Rolling Eyes
 
ExcelVBA即効テクニック研究室(その8)
http://web.archive.org/web/20130115194234/http://moug.net/faq/viewtopic.php?t=64202

投稿日時: 12/09/20 19:07:42投稿者: kanabun
からそのあとず〜〜っと、ご覧ください。
(ただし ぼくの記憶が薄れていたので、「行を返す」は 「列の集合体を返す」の
あやまりでした。 どちらにしても、「セルを返さなくなった」わけで、憲法9条の
解釈みたいに大変換が起きたのです!)

回答
投稿日時: 15/07/03 19:59:26
投稿者: kanabun

TopLeftCellプロパティが、Cellではなく、Columnを返すようになった!
このトピックというか 議論は このスレッドでは終わらなく、
 
(その9)
http://web.archive.org/web/20130115193935/http://moug.net/faq/viewtopic.php?t=64357
まで尾を引きずっています。

回答
投稿日時: 15/07/04 10:33:46
投稿者: mattuwan44

kanabun さんの引用:
mattuwan44 さんの引用:
UO3 さんの引用:
kanabun さんの引用:
近い例を挙げると、図形の、それが乗っかっ
ている左上セル を取得する TopLeftCellプロパティが、それまで「セル」を
返していたのに、あるバージョンから「行」を返すようになった。

 
えっ! そうだったんですか?
今まで、(結構長い間)全く気にもせずに、「セル」として扱ってきました。
で、心配になって、xl2013ですけど、たった今、検証しましたら、TopLeftCell は
「セル」になっていましたが?

2010で試してみました。
 
?activesheet.shapes(1).topleftcell.address
$C$4
 
となりますが、、、「行を返すとは?」

あれ? 即効テクニック研究室で一時大騒ぎしたのに?
ご存知なかった、ですか?(林修ふうに) :roll:
 
ExcelVBA即効テクニック研究室(その8)
http://web.archive.org/web/20130115194234/http://moug.net/faq/viewtopic.php?t=64202

投稿日時: 12/09/20 19:07:42投稿者: kanabun
からそのあとず〜〜っと、ご覧ください。
(ただし ぼくの記憶が薄れていたので、「行を返す」は 「列の集合体を返す」の
あやまりでした。 どちらにしても、「セルを返さなくなった」わけで、憲法9条の
解釈みたいに大変換が起きたのです!)

ご存じなかったです。
というか、見たかも知れませんが、特に興味がなかったかもです。
いろんな場面でCellsを書かなくて失敗してますし。。。
 
Sub test1()
    With ActiveSheet.Shapes(1)
        Application.Range(.TopLeftCell, .BottomRightCell)(1).Select
        Application.Range(.TopLeftCell.Cells, .BottomRightCell.Cells)(1).Select
    End With
End Sub
 
挙動確認しました。
TopLeftCell

BottomRightCell
とで、
矩形領域を取得したいときには、
Rangeオブジェクトのハンドル(?)がcolumnsになっているってことですね^^
ただ、片方のプロパティだけ使う場合は特に影響ないのかな?
 
個人的な意見ですが、
Valueを明示的に書くことを推奨するように、
Cellsも明示的に書くことを習慣にしてしまえばいいかなと思いました。
(この件に関して以外でも時々、Rangeオブジェクトの指定方法で失敗したりするので。)
 
Sub test2()
    Dim Rng As Range
    Dim c As Range
     
    With ActiveSheet.Shapes(1)
        Set Rng = Application.Range(.TopLeftCell, .BottomRightCell).Item(1)
    End With
 
    For Each c In Rng.Cells
        c.Select
    Next
End Sub

回答
投稿日時: 15/07/04 12:50:01
投稿者: UO3

kanabun さんの引用:
あれ? 即効テクニック研究室で一時大騒ぎしたのに?
ご存知なかった、ですか?(林修ふうに)

 
はい。mattuwan44 さん同様、知りませんでした。
こちらでも確認しました。確かに単一セルというところは間違いないけど
その「属性??」が「列」になってしまっていて、From/To なんかで抜きだすと
取得されるものは列だということなんですね。
 
とくにこの矩形領域からセルを取り出して処理する要件が今までなかったので
気が付きませんでした。これからも、あまりないかもしれませんがメモ、メモ。
 
勉強になりました。

回答
投稿日時: 15/07/08 18:11:23
投稿者: daive

ユーザーフォームをそのまま印刷したい。
http://www.moug.net/faq/viewtopic.php?t=72324
 
長らく、思考停止的に、使っているのが、
富士通 InstantCopy です、古くから、取説作成用で、お世話になっています、
マウスカーソル付キャプチャオプション有。
現在では、安くなり、工数かけるよりはと、システム品に標準、SCADAシステムでは要注意。
他には、無料系でも、有るようです。
かといって、自前ハードコピープログラムは、
昔からを作っていない事はないし、何度か作り直しもしています。
⇒味噌は、RGBAを、どの様に、インクに直すか、補完やエイリアス処理をどうするか
 印刷時の黒無視なども。
Microsoft でも、VB4.0時代から、何回か、画面ハードコピープログラムを
公開しています。(現在でも取得可能かどうかは、不明)

投稿日時: 15/08/16 12:48:29
投稿者: kumatti
投稿者のウェブサイトに移動

https://web.archive.org/web/20130322175258/http://www.moug.net/faq/viewtopic.php?t=65909
今朝方、Windows10をインストール致しまして、
yayadonさんに教わったUI Automationでの設定コードはWindows 10でも機能しました。
ありがとうございましたm(_ _)m

回答
投稿日時: 15/08/17 05:22:31
投稿者: yayadon

あ,どうもです。
なぜか,i なんてプリフィクスを付けてたんですね。
 
そういえば,ずいぶん昔のスレ(確かShapes.Range絡みのスレ)だったと思うのですが,
「ByVal Variant だけど 参照渡しもどき が原因」ていうのが正解なのに,
こちらには書かれなかったんですね。
 

回答
投稿日時: 15/08/17 12:44:53
投稿者: yayadon

Edge の拡張機能は,
JavaScript ベースならば,
メモリのライフサイクル管理は,いわゆる GC (Mark and Sweep)なんですかね。
GCレスだといいんですけど。
 
COM は,確定的デストラクタを利用して,スマートポインタを作成し,
それを用いて,動的なメモリのライフサイクル管理を行っています。
でも,
Mark and Sweep 方式の GC は,確定的デストラクタを受け入れてくれないでしょうから,
そこに,COMの居場所はあるんでしょうかね。(´・ω・`)
 
Edge の拡張機能は,Windowsアプリ ベース,つまり,新COM方式 のアドインになると思っていただけに,
ちょっとショックな近頃でした。
 

投稿日時: 15/08/18 07:50:42
投稿者: kumatti
投稿者のウェブサイトに移動

yayadonさん、勉強になりますm(_ _)m
 
---
 
かつてはMacにIEが実装された時代もありましたが、今やAppleの開発したレンダリングエンジンを実装したWebブラウザがWindowsの
既定のブラウザとは時代の趨勢を見る気がします。
 
Swift2もオープンソース化して予定はLinuxだけですが、Windowsに移植されるかどうか話題に上ってるとか。
PCのOSのシェアはWindowsの方が圧倒的なのに、舵を切ってるのはAppleの様な不思議な時代です。

回答
投稿日時: 15/08/18 11:03:58
投稿者: きぬあさ
投稿者のウェブサイトに移動

こんにちは。
 

yayadon さんの引用:
Edge の拡張機能は,Windowsアプリ ベース,つまり,新COM方式 のアドインになると思っていただけに,
ちょっとショックな近頃でした。

 
Edgeの拡張機能、詳細はまだよく分かっていませんが、Chromeの拡張機能のことを考えると、やっぱりJSベースなんでしょうねー。
 
・Microsoft Wants Google Chrome Extensions to Work on Edge with “Zero Work to Do”
http://news.softpedia.com/news/microsoft-wants-google-chrome-extensions-to-work-on-edge-with-zero-work-to-do-488282.shtml
 
上記記事だと“Extensions will be hosted in the Windows Store”なんてありましたが、いったいいつ頃登場するのか謎です(SR1かな?)。
 
 
Edgeのオートメーションに関しては、私もいろいろやってみましたが、Selenium WebDriverが鉄板だと思います。
(いや、Seleniumは必須じゃないですが、使った方が圧倒的に楽です。公式ブログでC#のサンプルコードも載ってますし…)
 
オープン戦略、標準化に力を入れているMS的にも、やはりIEのようなCOMオートメーションというのは・・・。
 
VBAからの操作?
大丈夫!そのうちきっとSeleniumbasic(selenium-vba)が対応してくれます!(適当)

回答
投稿日時: 15/08/18 22:17:24
投稿者: yayadon

きぬあさ さん,どうもです。
 
いろいろと情報ありがとうございます。
 
個人的には,
・別途インストールが必要無い もしくは Selenium WebDriver自体が Windows アプリ
・イベント が存在する
をクリアしないと難しいんじゃないかと思っています。
 

回答
投稿日時: 15/08/19 06:10:44
投稿者: yayadon

Ole Automation のコレクションオブジェクトですが,
Ole Automation の仕様上では,
・DISPID_NEWENUM (-4) の _NewEnum メソッドを持たないといけない
ということしか決められていません。
 
なので,本当は,
Count と Item は,必須ではないんです。
 

回答
投稿日時: 15/08/20 13:02:56
投稿者: きぬあさ
投稿者のウェブサイトに移動

こんにちは。
 
> 別途インストールが必要無い もしくは Selenium WebDriver自体が Windows アプリ
 
これは私も思います。
現状だとどうしてもEdge用のWebDriverが必須になってしまうので、インストールの手間が掛かります。
WebDriverをBase64文字列にしておいて使うときに元に戻す、なんてことも考えましたが、ライセンス調べてないし、それもそれで面倒なので止めました。
(そもそもEdgeのオートメーション自体、そこまでやるほどの需要なさそうですし…)
 
 
> イベント が存在する
 
OpenQA.Selenium.Support.Events.EventFiringWebDriver がわりと近そうな感じですかね・・・?
 
----------
5章 WebDriverのイベント
    5.1 EventFiringWebDriverとEventListenerクラスの紹介
    5.2 EventListernerのインスタンスの生成
        5.2.1 WebDriverEventListenerの実装
        5.2.2 AbstractWebDriverEventListenerの拡張
        5.2.3 WebDriverのインスタンスの生成
        5.2.4 EventFiringWebDriverとEventListenerのインスタンスの生成
        5.2.5 EventFiringWebDriverへの EventListenerの登録
        5.2.6 イベントの実行と検証
    5.3 様々な WebDriverのイベントリスナー
        5.3.1 .WebElementの値の変更の待ち受け
        5.3.2 WebElementのクリックの待ち受け
        5.3.3 WebElementの検索イベントの待ち受け
        5.3.4 ブラウザーの戻るナビゲーションの待ち受け
        5.3.5 ブラウザーの進むナビゲーションの待ち受け
        5.3.6 ブラウザーの navigateToイベントの待ち受け
        5.3.7 スクリプトの実行の待ち受け
        5.3.8 例外の待ち受け
        5.3.9 .EventFiringWebDriverからの EventListenerの登録解除
    5.4 まとめ
----------
http://www.oreilly.co.jp/books/9784873116952/ より
 
使ったことが無かったのでちょっと触ってみましたが、コレジャナイ感ありました(使い方が悪いのかな?)。
 

using System;
using OpenQA.Selenium.Edge;
using OpenQA.Selenium.Support.Events;

namespace EdgeSample
{
  class Program
  {
    public static void Main(string[] args)
    {
      EventFiringWebDriver edge = new EventFiringWebDriver(new EdgeDriver(@"C:\Program Files (x86)\Microsoft Web Driver"));
      edge.Navigating += new EventHandler<WebDriverNavigationEventArgs>(edge_Navigating);
      edge.Navigated += new EventHandler<WebDriverNavigationEventArgs>(edge_Navigated);
      edge.Navigate().GoToUrl("http://www.bing.com/");
    }
    
    private static void edge_Navigating(object sender, WebDriverNavigationEventArgs e)
    {
      Console.WriteLine("Navigating:" + e.Url);
    }
    
    private static void edge_Navigated(object sender, WebDriverNavigationEventArgs e)
    {
        Console.WriteLine("Navigated:" + e.Url);
    }
  }
}

 
何にせよEdgeはまだ出始めなので、今後に期待してます。
ConnectとUserVoiceでは結構フィードバック上がっているので、まだまだ変わっていくだろうと思います。
 
 
> Ole Automation のコレクションオブジェクトですが,
 
この話↓関連のことでしょうか。
 
https://twitter.com/kiyotoi/status/633443224586072065
 
> なので,本当は,
> Count と Item は,必須ではないんです。
 
なるほど!
Count無くても実はコレクション、なんてオブジェクトもあるわけですね(^^)

回答
投稿日時: 15/08/20 13:59:28
投稿者: yayadon

きぬあさ さんの引用:

使ったことが無かったのでちょっと触ってみましたが、

まだ試していませんが,
いや,話を振ったかいがありました。
本当は,自分で調べないといけないのに,ありがとうございます。m(__)m
 
edge.Navigating
edge.Navigated
 
自分は,ユーザーが絡まない処理は,WinInet or WinHTTP でやって,
IE 自体はユーザーに操作させるときに,IE の オートメーションを使っています。
で,
Url で場合分けして,ログ等をとるなどに使っています。
 

回答
投稿日時: 15/08/20 14:44:35
投稿者: yayadon

きぬあさ さんの引用:

> Ole Automation のコレクションオブジェクトですが,
 
この話↓関連のことでしょうか。

それを,たぶん,どこか経由で見たのがきっかけですが,
COM and ATL 3.0 には,
525ページの中ごろに,
 only Count(), Item(), and _NewEnum are mandatory
と書いてあるので,自分もそう思っていたのですが,
なぜか,仕様書では _NewEnum しか決められていないので,書いてみました。
 

回答
投稿日時: 15/08/20 17:39:46
投稿者: yayadon

edge.Navigating
edge.Navigated
 
元のソースコードを見てみたんですが,
Selenium WebDriver でテストした時のみ発生する感じですね。
 
 
 
 
 

回答
投稿日時: 15/08/20 22:05:50
投稿者: きぬあさ
投稿者のウェブサイトに移動

yayadon さんの引用:
元のソースコードを見てみたんですが,
Selenium WebDriver でテストした時のみ発生する感じですね。

 
そうなんですよね・・・。
やってみて「あれ?これナンカチガウ・・・」ってなりました Confused

回答
投稿日時: 15/10/23 15:05:23
投稿者: きぬあさ
投稿者のウェブサイトに移動

VBAとは関係が無いですが、UWSCがMicrosoft Edgeに対応したそうですね。
 
http://www.uwsc.info/sample.html#n38
 
EdgeはCOMサポートしていなかったはずなので、どういった仕組みにしているのか?
UIAか Internet Explorer_Server -> IHTMLDocument2 -> IWebBrowser2 しているのか??

回答
投稿日時: 15/11/16 19:13:04
投稿者: UO3

このようなお願いレスは不適切かも・・と思いながら。
 
VBA Q/Aのほうに
API GetPixel や ウィンドウ属性処理関連の 2010と2013での結果の差異について
http://www.moug.net/faq/viewtopic.php?t=73063&sid=23e99ab931fc7af4aab415f2c702651f
 
の質問をアップしております。
是非、ご覧いただき、皆さんのアドバイスを頂戴したいと願っております。

回答
投稿日時: 15/11/16 23:16:56
投稿者: K.Hiwasa
投稿者のウェブサイトに移動

UO3さん
 
難しいですね。
ちょっと挑戦しましたが、思うような結果を得られてません。
少しだけできたこともあったので残しておきます。

回答
投稿日時: 15/11/17 07:26:20
投稿者: UO3

K.Hiwasaさん
 
ありがとうございます!
商店街の呼び込みのような、品のないことを・・・とも思ったんですが
お願いしてよかったです。

投稿日時: 16/02/10 16:43:14
投稿者: kumatti
投稿者のウェブサイトに移動

https://gist.github.com/kumatti1/78cb31abab7903881afd
以前、yayadonさんに教わった「ディスプレイ」のUI Automationでの設定コードはWindows 10 build 14257で、
件のComboBoxは、ウィンドウレスコントロールからウィンドウを持つと言う転機を迎えた様です・v・
 
以上、ご報告まで(`・ω・´)ゞ

回答
投稿日時: 16/03/16 11:30:20
投稿者: ふるふる
投稿者のウェブサイトに移動

ちょっとしたメモ。速効テクニックに載せてくれるとありがたい。
 
Access 2010以降で、データマクロという機能があります。
通常のマクロと違って、アクションが制限されていて、どうやったらデータマクロから通常のVBAのプロシージャが呼び出せるか調べてました。
通常のデータマクロ(挿入後処理とか削除後処理とかのマクロ)では無理っぽいですが、名前付データマクロ(引数を必要とさせる)を用意し、通常のデータマクロから名前付データマクロを呼び出す際に引数の指定でVBAの関数をかますことで可能になります。
 
モジュール側で
'Module1
Public Function SampleTBL_Inserted(ParamArray args() As Variant)
' 処理。 args()は挿入後処理マクロの対象となったレコードの各フィールド値を想定している
 SampleTBL_Inserted = "正常終了"
End Function
などを用意し、名前付データマクロ(名前を"sample")では
パラメーターを追加します。(名前:"rec" )
挿入後処理のデータマクロで「データマクロの実行」アクションを追加し、マクロ名を上記で用意したマクロにします。パラメーターの設定で、
rec = [    ]
とあるのでこの設定を
rec = [ SampleTBL_Inserted([F1],[F2]・・・)  ]
とすることで、 SampleTBL_Inserted 関数を呼び出すことができました。
SampleTBL_Insertedの戻り値の文字列をつかって、名前付データマクロ内で「イベントのログ記録」アクションに利用するといいでしょう。
 
 

回答
投稿日時: 16/06/10 21:12:23
投稿者: mr_hige
メールを送信

最近

  With ActiveSheet
        .Range(CpyArea).Copy
        .Range(PstPos).Select
        .PasteSpecial Format:="図 (拡張メタファイル)" 
    End With

ではエラー
  With ActiveSheet
        .Range(CpyArea).CopyPicture Appearance:=xlScreen, Format:=xlPicture
        .Range(PstPos).Select
        .PasteSpecial Format:="図 (拡張メタファイル)" 
    End With

ペーストするときの設定だけでは拡張メタファイルは作れないのでしょうか?

回答
投稿日時: 16/08/08 20:33:30
投稿者: mr_hige
メールを送信

こんばんわ。
 
再帰プロシージャの基本的な『形』とはなんでしょうか。
再帰プロシージャの
 引数条件(引数にする条件や、引数にしてはいけない条件など)
 終了条件
 条件が満たされない場合の処理
 その他
など、再帰プロシージャの構成がいまいちわかりません
一般化するとどんなことが言えるのでしょうか?

回答
投稿日時: 16/08/09 13:13:10
投稿者: 古参兵

識者の方の回答待ちで、一般的なコメントだけですが。
 
コマーシャル(商用計算)の世界でVBAと遊んでますが、
唯一ファイル検索(例:Media Playerの歌検索)の際にFSOで全ファイル検索してます。
それ以外では必要性を感じたことがありません。
他に DIR とミックスしたりもありそうですが。(kanabunさんだったと思います)
 
説明できるほどのスキルはありませんが、
 
[再帰処理 TANAKA] 
 
で、詳しい説明付でサンプルが出ています。
(前半の FileSearch は スキップです)
http://officetanaka.net/excel/vba/tips/tips36.htm
 
その他ならWEB検索で 階乗計算みたいなのもありましたが、
通常のループで十分でしょう的な説明がありました。
 
 
 

回答
投稿日時: 16/08/09 13:44:09
投稿者: mattuwan44

>ペーストするときの設定だけでは拡張メタファイルは作れないのでしょうか?
 

Sub test()
    Dim Pic As Picture
    
    Range("A1:C7").Copy
    Set Pic = ActiveSheet.Pictures.Paste
    Application.CutCopyMode = False
    With Range("E1")
        Pic.Top = .Top
        Pic.Left = .Left
    End With
End Sub

 
selectした方が、書く行数が少ないですね。。。
でも、それでいいのか。。。。。
 
図として貼り付けたら、拡張メタファイル?
 
ビットマップ形式で保存したら、PNGで保存されるのかなぁ。。。
 
名前を付けて保存してから、拡張子をZipに変えて開いてみました。

回答
投稿日時: 16/08/09 14:51:42
投稿者: mattuwan44

>再帰プロシージャの構成がいまいちわかりません
>一般化するとどんなことが言えるのでしょうか?

無限ループにならないように、
終わりを判断する条件分岐があればあとはどうとでも、お好きなようにされたらいいと思います^^
 
再帰的とは
http://ews2.cc.niigata-u.ac.jp/~takeuchi/tbasic/BackGround/Recursive.html
 
分かり難ければシンプルな例題で^^
http://qiita.com/xxxx7/items/60296f94a6ebdf9bdc03#%E5%86%8D%E5%B8%B0%E9%96%A2%E6%95%B0
 
ちなみに、、、
↑のサンプルで、
1回目に呼び出されたプロシージャの変数iと、
2回目に呼び出されたプロシージャの変数iは、
全く別物ということは理解されてますかね?(知っているなら失礼しましたです。)
なので再帰処理を使うと、たくさんの変数を用意せずに、
簡便にコードを書ける場合があるという事だと思います。

回答
投稿日時: 16/08/14 13:16:41
投稿者: mr_hige
メールを送信

こんにちは。
いつもありがとうございます。孫が来てて・・・ご無沙汰しました。

引用:
With ActiveSheet
        .Range(CpyArea).CopyPicture Appearance:=xlScreen, Format:=xlPicture
        .Range(PstPos).Select  '//ここと次の行が一緒になればもっと良い
        .PasteSpecial Format:="図 (拡張メタファイル)"
    End With

引用:
Range("A1:C7").Copy
    Set Pic = ActiveSheet.Pictures.Paste
    Application.CutCopyMode = False
    With Range("E1")
        Pic.Top = .Top
        Pic.Left = .Left
    End With

後者の写真も図柄を拡大すると、元の細かい図柄のまま面積が広く=拡大されぼやけもしませんので、拡張メタファイルだと思われます。
行数は前者が1行少ないだけですが、大差ありません。どちらがスマートかでしょうか?
 
1回目と2回目に呼び出されたプロシージャの変数iが違うことは分かります
分かりますが、全体的に理解がまだまだです。iこの辺がポイントなんでしょうね。
今現在は数独の解を見つける作業に挑戦中で、再帰を使ってと思ったのですが難しいのです
再帰を使わない方法もこれから研究しようかと。今少し時間が必要です。

回答
投稿日時: 17/02/07 08:24:40
投稿者: mr_hige
メールを送信

リストをクリックした時のボタンが表示されたりされなかったり・・・
このシートにはシェイプ図形や写真があり、どうやらこれらが関係していそうだがはっきりとは分からない
色々いじる中で、先日まではボタンが一瞬だけ表示されたが、今は全く表示されない。
その間何をしたのか、その違いも判らない。
つまりほとんど前と同じだと思うが、現象としては異なっている。
ネットもみて調べたが、だめだった。
   Win10 EXCEL2016 使用

回答
投稿日時: 17/02/09 16:25:45
投稿者: mr_hige
メールを送信

つづき
そこで念のため『修復』をしてみた!!
 
結果、重大事故!
 
EXCELを立ち上げようとしたらアカウントを求められた
書き込むと、インストールした時のアカウントではなかったようで、これではダメと。
 
次にプロダクトキーのほうほうもあったので、あらかじめメモしておいたキーを打ち込むとそれはOFFICE2016用ではないと・・・
カードは仕舞無くし、マル2日探し続けたが無い!
 
マイクロソフトのサポートセンターに連絡
電話やチャットを長ーーい時間待たされた。
丁寧な言葉を使うが、内容はロボットみたいに冷たい。結局再購入を勧められた
せっかく家内からもらう小遣いをためて買ったのに・・・
 
ネットにはソフトの紹介がありそれも試みたが、最新のOFFICEのせいなのか、キーをPC内から見つけ出せなかった・・・
 
まだ購入して2か月もたってないのに! 頭にきたが、来ただけだ。トホホ途方に暮れている

回答
投稿日時: 17/02/10 14:16:42
投稿者: mr_hige
メールを送信

プロダクトキー捜索活動3日目
引き出しの端の方にビニール袋に入ったキーを発見!!
うまくゆきました。
マイクロソフトも少し余分なことをやり過ぎかも

回答
投稿日時: 17/02/28 15:21:17
投稿者: UO3

またまた、温泉街の呼び込みのようで恐縮ですがVBA掲示板に
 
http://www.moug.net/faq/viewtopic.php?p=476365#476365
ConnectToConnectionPoint と ATTRIBUTE文
 
このトピを立ち上げ質問をしております。
是非、閲覧いただき、ご教授いただければと思っております。
 
よろしくお願いします。

投稿日時: 17/03/03 08:34:31
投稿者: kumatti
投稿者のウェブサイトに移動

http://atata.sakura.ne.jp/net/chap24.html
https://gist.github.com/kumatti1/7c400ee7d3cab3f523e66725e3e38465
最近、知ったのですがExcelのWorkbookは、「IPrint」を実装してるそうです・v・

投稿日時: 17/04/06 08:40:45
投稿者: kumatti
投稿者のウェブサイトに移動

春の大型アップデートである「Windows 10 Creators Update」が始まった様です。
https://support.microsoft.com/ja-jp/help/4014184/windows-10-creators-update-here
 
ただ、DPI Scaling に於ける旧来の設定ダイアログは削除されたので、レジストリで設定する他ありません。
https://www.deskmodder.de/wiki/index.php?title=Nur_die_Textgr%C3%B6sse_%C3%A4ndern_nicht_mehr_vorhanden_Windows_10
 
 
※ ISOでも提供されています。

回答
投稿日時: 17/04/08 08:24:01
投稿者: snan

Windows 10 Creators Update(Ver1703)をインストールしてみました
 
Windows 10 Anniversary(Ver1607)からアップグレード
3年前購入のノートPCで約2時間(DVDメディアでアップグレード)
USBメモリにすると少し早く終わった感じです
 
新規でWindows 10 Creators Update(Ver1703)をインストール
インストール中にコルタナ君が大きな音量で説明が始まるのでボリュームを小さくしないと周りに迷惑
インストールは基本以前と大きくは変わっていない感じ
特に迷わず進められました
プログラムと機能のWinodwsの機能の有効化または無効化の.NET Framework3.5を有効にしようと
WindowsUpdateからで更新するとエラーになりました
このためインストールメディアからPowerShellで有効化しました
アプリケーションのインストールもOffice2013やウイルス対策ソフトなど市販されているもの
フリーソフトなど特に問題なくインストールはできました
後は使用してみないと正しく動くかは検証が必要だけど・・・
 
今回インストールして一番びっくりしたのはチェックディスクと最適化が速い・・・
起動ディスク300GBほどを数分でチェックディスク終了 しかも再起動しない
とりあえずインストールしてみましたって所です
今後検証しないと・・・・

回答
投稿日時: 17/04/18 16:43:49
投稿者: mr_hige
メールを送信

Windows 10 Creators Updateをインストールして、結果的には大変なことになってしまった。
 
元もwin10
結果、文字が小さくなり醜い。大きく設定するとボケる
またメニュの右クリックで表示されていた、コントロールパネル等が表示されず、例えばアプリのアンインストールはどこからだ・・・など訳が分からなくなった。
 
そこで、復元ポイントから元のWin10へ
すると、WEBアプリ、例えばGOOGLEを開くとエラー(パスワードが盗まれた可能性・・・みたいなエラー)
もちろんTwitterなどのサイトのアドレスを入れて実行してもだめ。
マイクロソフトにチャットで質問した(混雑しトータル3日程要した)が、結局ダメ
 
覚悟を決め、win10の初期化を行い、設定も最初からやり直す羽目に
するとメラーにGOOGLEからパスワードがぜい弱で・・・、ブロックしていた旨の通知が来た
 
何かね、ちょっとやりすぎな気もした
実は元に戻すまでの間に、スマホやPCのアカウント整理や、パスワードの変更作業などをしていたのだ。
多分これが引っかかったのではないかと思う。
 
Windows 10 Creators Updateは当分するつもりはない
 

投稿日時: 17/05/03 07:20:22
投稿者: kumatti
投稿者のウェブサイトに移動

 
・モニタのお話
 
昨今の液晶モニタのバックライトはLEDであり、特に断りが無ければPWM制御によって明暗を調整しています。
これは、輝度を落とす際にちらつき(フリッカー)を伴う場合があり、
(一部の高級モニタはちらつきの発生しないDC制御)
 
これを改善するには、工場出荷時設定である輝度を最大で使用すればいいのですが、さすがに明る過ぎて凡そ実用に耐えません。
なので、ユーティリティ側で調整する事になりますが、「明るさ」を落とすと色味が変わり青みが増すので、既定値のまま、変えられません。
必然、「コントラスト」のみで調整する事になりますが、これは既定値が「50」で下限が「40」と調整範囲が狭いです。
そこで、レジストリを直接、書き換えますが「20」だと相当、暗くなり、「30」辺りがベストなのではと思いました。
変更箇所はRGB分、3箇所です。
 
0や負数も指定出来ますが見た目の上で変更されるだけであり、実際に反映される範囲は決まってる様です。
(実際の下限・上限はどれ位なのかは調べていない)
 
レジストリ書き換え後は、「コントラスト」項目のスライダーを動かすと既定値に戻ってしまうので、
「明るさ」項目のスライダーを動かすと設定が実際に反映されます。
 
※ IntelのiGPUに限ります。AMDのAPUまたは、外部GPU(d GPU)使用の情報は知りません。
 
 
参考URL
https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AA%E3%83%83%E3%82%AB%E3%83%BC
http://offgao.blog112.fc2.com/blog-entry-49.html

投稿日時: 17/05/03 07:22:32
投稿者: kumatti
投稿者のウェブサイトに移動

ちなみにバージョン1703から対応した「夜間モード」が有効で、「コントラスト」が30だと個人的にベストかなと判断しています・ω・

回答
投稿日時: 17/05/18 05:48:02
投稿者: かすみの

最近RPA(Robotic Process Automation)界隈を触る機会があったのですが、
定期的に質問にあがっている(ように感じる)、
「Webから何かとってきてExcelに流し込みたい」
であれば、VBAを組み込むよりもシンプルに実現できそうに感じました。
 
まぁ、追加導入の方がハードル高いと言われればそれまでですけどね。
 
結局のところ、どこで、どう 自動化するのかって話になるのですが、
やはり複数の体系をまたぐのであれば、ある一か所の内部で頑張るよりも、
最初から外側からの制御を指向したほうが合理的だなぁと思いました。

投稿日時: 17/10/20 07:27:13
投稿者: kumatti
投稿者のウェブサイトに移動

日本時間では18日の午前2時に配信が開始された定例の秋の大型アップデートですが、
負荷を分散する為か順次、配信され、どの途、Windows Updateによって行われるので、回避出来ません。
 
なので、待ってられないので、ISOを落としてマウントして、アップデートしました。
この方法だと、クリーンインストールに較べて遥かに時間が掛かり、自分の環境だと1時間40分程です。
 
削除された「テキストやその他の項目のサイズ調整」は、何らかのUIを用意して欲しかったのですが、そんなに大仰な事なのだろうかと。
(*´・ω・)(・ω・`*)ネ-
 
デバイスが認識されないという往時のIP版の様な現象も確認出来ましたが、
散々、当時かかずらされたので、「デバイスの電源をOFFにし、PCを再起動する」と対照法がまた、役に立ちました。

投稿日時: 17/11/03 06:58:09
投稿者: kumatti
投稿者のウェブサイトに移動

・雑感
 
 
「複数のIEを操作するには」
http://bbs.wankuma.com/index.cgi?mode=al2&namber=85362
このディスパッチIDで呼び出さないとエラーになる現象は、固有型で受けないとコケるのと同じ状況なのだろうか。
が、VBAでIDispatch::Invokeは中々に大変である。
 
「VBAでExcelを使う - Qiita」
https://qiita.com/palglowr/items/04250eb1a8a873fbf9d2
 
DISPPARAMSの宣言だけ、何故か無いので。

Private Type DISPPARAMS
    rgvarg As LongPtr
    rgdispidNamedArgs As LongPtr
    cArgs As Long
    cNamedArgs As Long
End Type

回答
投稿日時: 18/01/14 17:45:05
投稿者: baoo

2ヶ月前にKumattiさんのコメントを見たときに書こうと思ったのですが、
なかなかまとまらず時間が経ってしまいました。
実は偶然というか、私も9月頃「VBAでExcelを使う - Qiita」を見たばかりでした。
ただ、この記事もそうですが技術がいろんなところに繋がっているの体感しました。
 
1年くらい前にあるアプリケーションのステータスバーの数値を取得したいことがあったんですが、
定番のGetWindowTextとかWM_GETTEXTやUIAutomationを使っても取得ませんでした。
何故取得できないのかですが、ステータスバーですからそこに表示したものを
別で利用するとも考えられず、つまりBitbltなんかで描画しているだけなので
取得できないのではと推測しました。
それでGDI+を使って画像から数値を取得することにしたんです。
(なんか、昔もどこかで似たようなことをしてたような気がします。)
 
ところがステータスバーの画像をGDI+で取得しても違う場所の画像が取れるんです。
それでそのアプリケーションのメインウィンドウ全体の画像をBitblt等で取得してみたら、
見た目と違ってメインウィンドウ内にm/nサイズで縮小表示されていました。
改めてアプリケーションの画面を見てみると少し表示が荒い。
色々調べて、どうやら拡大鏡APIってので拡大表示しているらしい。
それで結局m/nの座標位置からステータスバーの画像を取得して
それを元に数値を取得することができました。
 
ところで、GDI+についてですが、私が初めて扱ったのはVBAでではなく、
AutoItという言語が最初だったと記憶しています。
AutoItを使う以前は他アプリの操作言語としてUWSCを使っていたのですが
AutoItの方が色んなことができると思ってこちらを使うようになっていたんですね。
しかしUWSCでは出来てAutoItでは出来ないことがありまして、
画面の中から指定の画像と同じ場所を探すというのができなかった。
(画像のボタンを押すというようなことが出来なかった。)
それでGDI+を使ってその機能を作成したというのが最初でした。
AutoItではWin32APIも呼び出せるのですが、それとは別にユーザーが作った関数が
ほぼ正式に沢山取り込まれていて、かなりのWin32APIは標準の関数のように使用できました。
そしてそれらは全てヘルプに記載があり、ヘルプ内のサンプルコードを
実際のエディタに呼び出すことが出来るようになっていました。
それからVBAのAPI宣言のようなものもIncludeファイルも用意されていたこともあって、
必要ありませんでした。
画面から指定の画像と同じ場所を探すというのは画像左上の点(もしくは特定の点)の色と同じ色を
画面の中から探し、見つかったら画像と同サイズで切り出してビットデータを作成して
画像のビットデータと比較するわけですが、この比較するのにうまい方法が分からなかった。
それでネットで探して見つけたのがmemcmpでした。
当時、cdecl?何それ?状態でしたが、AutoItのDllCall(API呼出し関数)は
cdecl呼び出しAPIも使用できたんですね。
もっとも、見つけてきたのはAutoItmemcmpを実行するサンプルそのものなので、
殆どコピペなんですが、何とかUWSCと同じ機能を実現できました。
 
さて、ステータスバーに表示される数値を取得できてから私は拡大鏡APIに興味がありました。
それで最近時間が出来たので拡大鏡APIのサンプルプログラムを探してきてVBAに直してみたんですね。
ところがこれがすぐ落ちるわけです。
どこで落ちてるかを調べるとMagSetWindowSourceという関数で落ちている。
それでMSDNでよく見てみたら引数に与えるRECT構造体がポインターになっていないんです。
大村あつし氏の本でも構造体をByRefで渡すことは想定していないようなことが書かれていますが、
私もMSDNの記載からDeclare宣言を作ると結構間違えたりするので、
APIViewerやネットから拝借させて頂くことが多く、こういう場面に遭遇してきませんでした。
でも、よくよく考えてみたらポインタではないということはRECT構造体の各メンバーが
それぞれ渡される訳で4つのLong型変数をByValで指定すれば良いと気づいて動かすことが出来ました。
そして改めて調べてみるとSetWindowPosとかWindowFromPointとか構造体を個々にバラした
宣言も結構あると知りました。
逆にポインタの場合は例えばGetWindowRectなんかの場合、4つの連続したLong型の領域を確保して、
ポインタつまりその先頭をByRefで渡せば同じことなわけですよね。

Public Declare Function GetWindowRect Lib "user32" _
    (ByVal hWnd As Long, _
    lpRect As Long) As Long
Sub Test()
    
    Dim hWnd As Long
    Dim lngRect(3) As Long
    Dim lngRet As Long
    
    lngRet = GetWindowRect(Application.hWnd, lngRect(0))
    
    Debug.Print "Left:" & lngRect(0)
    Debug.Print "Top:" & lngRect(1)
    Debug.Print "Right:" & lngRect(2)
    Debug.Print "Bottom:" & lngRect(3)
    
End Sub

拡大鏡APIのサンプルを動かした後、良く聞くDispCallFuncを自分は使ったことが無いので、
どういうことが出来るのか、何か動かしてやろうと思って色々調べていたのです。
そこで最初に見つけたのが、cdecl呼出しのAPIも動かせるという話でした。
これを使えばAutoItで使っていたmemcmpが使えると思い、サンプルを書いてみたのですが、
ビックリするほど早いですね。
真ん中のあたりで1バイトだけ変更した2つの500Mbyte位のファイルを
一気にバイト配列に読み込んで比較するという危険なことをしてみましたが、
単純に1バイトずつ比較した場合もかなり早いですけど、それに比べて1/3の時間で済みました。
DispCallFuncの勉強をしたらたまたま初めてGDI+を使用するプログラムを組んだ時に
使用したmemcmpをVBAでも使用できることが分かったのですね。
 
そして更にDispCallFuncを調べていて「VBAでExcelを使う - Qiita」を見たわけです。
これを応用すれば、かつてこちらで教えて頂いたUIAutomationのElementFromPointを
使用するためにmidlを使ってdllを修正するようなことをしなくても動かせるのではないかと
思いました。
そしてかつてElementFromPointがなぜそのままでは動作しなかったのかが、
MagSetWindowSourceと同じように引数のPOINTAPIがポインタでなかったからというのを
ここに至って初めて思い出したのでした。
Private Declare Function CLSIDFromString Lib "ole32" _
    (ByVal OleStringCLSID As Long, _
    ByRef cGUID As GUID) As Long
Private Declare Function CoCreateInstance Lib "ole32" _
    (ByRef rclsid As GUID, _
    ByVal pUnkOuter As Long, _
    ByVal dwClsContext As Long, _
    ByRef riid As GUID, _
    ByRef ppv As Long) As Long
Private Declare Function DispCallFunc Lib "OleAut32.dll" _
    (ByVal pvInstance As Long, _
    ByVal oVft As Long, _
    ByVal cc As Long, _
    ByVal vtReturn As Integer, _
    ByVal cActuals As Long, _
    ByVal prgvt As Long, _
    ByVal prgpvarg As Long, _
    ByVal pvargResult As Long) As Long
Private Declare Function StringFromGUID2 Lib "ole32" _
    (ByRef rguid As GUID, _
    ByVal lpsz As Long, _
    ByVal cchMax As Long) As Long
Private Const CLSCTX_INPROC_SERVER = &H1
Private Const CC_STDCALL = &H4
Private Const IID_IUIAUTOMATION = "{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}"
Private Const IID_CUIAUTOMATION = "{FF48DBA4-60EF-4201-AA87-54103EEF594E}"
Private Type GUID
     Data1 As Long
     Data2 As Integer
     Data3 As Integer
     Data4(0 To 7) As Byte
End Type
Private Type DISPPARAMS
    rgVarg As Long      ' pointer to array of variant agruments
    rgDispID As Long    ' pointer to array of DISPIDs of named argument
    cArgs As Long       ' number of arguments
    cNamedArgs As Long  ' number of named arguments
End Type
Sub DispGUID(objGuid As GUID)

    Dim lRet As Long
    Dim buf(100) As Byte
    lRet = StringFromGUID2(objGuid, VarPtr(buf(0)), UBound(buf) - 1)
    Debug.Print "lRet:" & lRet

    Dim sTmp As String
    sTmp = buf
    Debug.Print Left$(sTmp, InStr(sTmp, vbNullChar) - 1)

End Sub

Sub UseAutomationByCom()

    Dim i As Long
    Dim lRet As Long
    Dim iidCuiAuto As GUID
    Dim iidIuiAuto As GUID
    Dim pAuto As Long
    Dim IElem As IUIAutomationElement

    lRet = CLSIDFromString(StrPtr(IID_CUIAUTOMATION), iidCuiAuto)
    Debug.Print "lRet:" & lRet
    Call DispGUID(iidCuiAuto)

    lRet = CLSIDFromString(StrPtr(IID_IUIAUTOMATION), iidIuiAuto)
    Debug.Print "lRet:" & lRet
    Call DispGUID(iidIuiAuto)

    'Create CUIAutomation
    lRet = CoCreateInstance(iidCuiAuto, 0, CLSCTX_INPROC_SERVER, iidIuiAuto, pAuto)
    Debug.Print "lRet:" & lRet
    
    'ElementFromPoint
    Dim lngX As Long
    Dim lngY As Long
    Dim vRet As Long
    Dim vArgs(0 To 2) As Variant
    Dim vt(0 To 2) As Integer
    Dim pArgs(0 To 2) As Long

    lngX = 1000
    lngY = 1000

    vArgs(0) = VarPtr(ByVal lngX)
    vArgs(1) = VarPtr(ByVal lngY)
    vArgs(2) = VarPtr(IElem)

    For i = 0 To 2
        pArgs(i) = VarPtr(vArgs(i))
        vt(i) = VarType(vArgs(i))
    Next i

    lRet = DispCallFunc(pAuto, 28, CC_STDCALL, vbLong, 3, VarPtr(vt(0)), VarPtr(pArgs(0)), VarPtr(vRet))
    Debug.Print "lRet:" & lRet & " vRet:0x" & Hex(vRet)
    Debug.Print IElem.CurrentClassName
    
End Sub

あの時、ElementFromPointが5番目ではなくて8番目なのが分からないと言って
IUnknownインターフェースの3つを足すというのを聞いた気がするのですが、
あの時もDispCallFuncでどうにかしてやろうと試行錯誤していたのかなあ。
残念ながらやり取りをすっかり忘れてしまっています。
きぬあささんの所のmougleで検索しても見つかりません。
midlで作成したdllの日付を元にInternetArchiveで探したところ、
Excel(VBA)のページ内にトピックス(タイトル)は見つけました。
それによると13/12/28に投稿していたんですが、そのページ自体は保存されていません。
 
しかしそんなことを思いながらInternetArchiveのExcel(VBA)のページから
給湯室のリンクをクリックしてクラス研究室5を覗いてみたらタイムリーな話題がありました。
恐らく、当時それを見て質問したんですね。
なんか見覚えもあります。
正に?車輪の再発明というわけです。
でも、自分の技術がやっと追いついてきたということなので良しとします。
クラス研究室も全て保存したつもりでしたが5があること自体忘れていたので、
今回InternetArchiveから保存させて頂きました。
 
なお、ElementFromPointのソースですがQiitaを参考に書きましたが、
実際に使う場合は下記が現実的ですね。
'IUIAutomationのElementFromPointはByvalでPOINTAPIを渡すのが正しいので
'現状ExcelVBAではそのままでは使うことが出来ない仕様を回避する。
'
'  cuiAuto:既に生成済みのCUIAutomation、
'  pt:取得するElementの位置
'
Public Function AutomationElementFromPoint(cuiAuto As IUIAutomation, pt As POINTAPI) As IUIAutomationElement

    Dim lRet As Long
    Dim pAuto As Long
    Dim IElem As IUIAutomationElement
    Dim i As Long
    Dim lngX As Long
    Dim lngY As Long
    Dim vRet As Long
    Dim vArgs(0 To 2) As Variant
    Dim vt(0 To 2) As Integer
    Dim pArgs(0 To 2) As Long

    pAuto = ObjPtr(cuiAuto)

    lngX = pt.x
    lngY = pt.y

    vArgs(0) = VarPtr(ByVal lngX)
    vArgs(1) = VarPtr(ByVal lngY)
    vArgs(2) = VarPtr(IElem)

    For i = 0 To 2
        pArgs(i) = VarPtr(vArgs(i))
        vt(i) = VarType(vArgs(i))
    Next i

    'ElementFromPointはIUIAutomationの8番目->(8-1)*4=28
    lRet = DispCallFunc(pAuto, 28, CC_STDCALL, VbVarType.vbLong, 3, VarPtr(vt(0)), VarPtr(pArgs(0)), VarPtr(vRet))
    Debug.Print "lRet:" & lRet & " vRet:0x" & Hex(vRet)

    Set AutomationElementFromPoint = IElem

End Function

こことの関わりも、たっくさんのListViewの質問の中でAbyssさんがListView上に
Editコントロールを置いてという話を見つけたのが最初だと思います。
当時私もAutoItで同じことをやっていたんですね。
もっとも、私の方はEditコントロールというよりはTextBoxというのが正しい。
つまりCreateWindowではなくAutoItで用意された標準の命令でやっていたわけですけど。

回答
投稿日時: 18/01/14 22:41:21
投稿者: baoo

改めて見直してみたら
 
>大村あつし氏の本でも構造体をByRefで渡すことは
「構造体をByValで渡すことは」の間違いですな。

回答
投稿日時: 18/05/27 13:45:53
投稿者: simple

雑談スレッドの再掲( 投稿日時: 18/05/01 22:41:36 )
 
> 雑談ということで、私が聞いているIT関連の Podcastを紹介しましょう。(いずれも無料)
> (1)
> 宮川達彦さんのPodcast
> http://rebuild.fm/
> (2)
> 植山類さんのPodcast
> https://turingcomplete.fm/
> (3)
> 森田創さん向井淳さんのPodcast
> Misreading Chat
> https://misreading.chat/

twitter に同じ感想を書いた人がいました。
> loleco‏ @lolecov
> #rebuildfm #misreading #tcfm が一気に来てた。
> 22:32 - 2018年5月13日

 
宮川さんのrebuildに森田さんが登場した
http://rebuild.fm/206/
は神回でしたね。
特に後半、engineerとしての高い志が感じられる回でした。

回答
投稿日時: 18/05/27 19:20:19
投稿者: simple

mougブログというものがあります。
私は殆ど見たことがないのですが、たまたま覗いてみたら、
こんなビデオがありました。
 
かなり要領よくPythonの紹介をしていると思いました。
 
◇【アオテンビデオ】
1日でわかるPythonの基本〜Pythonを学ぶ理由と効率的な学習方法〜
https://aoten.jp/store/detail.html?mid=166&no=ai_o180216

回答
投稿日時: 18/08/04 00:00:15
投稿者: MMYS

内容がVBAからそれてしまうのでこちらにお借りして書かせてください。
http://www.moug.net/faq/viewtopic.php?t=77337
 

simple さんの引用:
今回のようにSystem.Drawing.dllだけがあるという状況でも、
COMコンポーネントにすることが可能なんですか。

下記リンク先ではWebClientクラスをラップしてますが、
今回のケースはBitmapクラスをラップすれば可能でしょぅ。
 
VBAで独自の.NETライブラリを使うには?[VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/1063vbausedotnet/vbausedotnet.html
 
C#でVBA向けの.NETライブラリ(COMコンポーネント)を作成するには?[C#]
http://www.atmarkit.co.jp/fdotnet/dotnettips/1064combycs/combycs.html
 
 
 
他にも下記のサイトを参考にしてください。
 
VBAまたはVBSからCOM経由で使用できる.NETのライブラリの作成方法
https://qiita.com/mima_ita/items/efcd1a6ea86f09047984
 
C# で COM コンポーネントを公開する
http://tech.nitoyon.com/ja/blog/2008/07/31/c-sharp-com/
 
C# で COM オブジェクトを作ってみる
https://qiita.com/tomochan154/items/1ce33f2aef167c0fed9d
 
 
 
統合開発環境が動作原理をブラックボックス化してしまって
原理がよくわかりません。なので
詳細を知りたければ下記がおすすめ。
 
VBAから扱えるDLLをC#で書いてみる。
https://www.ka-net.org/blog/?p=5464
 
Excel から使うマネージDLL を作る。
http://supermab.com/wp/excel-%E3%81%8B%E3%82%89%E4%BD%BF%E3%81%86%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8dll-%E3%82%92%E4%BD%9C%E3%82%8B%E3%80%82/
 
WSHのCreateObject関数の引数のCOM識別子「ProgID」「CLSID」(GUID)とは何なのか解説。Windows内のActiveXオブジェクトを一覧表示して確認するコマンド
http://computer-technology.hateblo.jp/entry/2016/01/06/WSH%E3%81%AECreateObject%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AECOM%E8%AD%98%E5%88%A5%E5%AD%90%E3%80%8CProgID%E3%80%8D%E3%80%8CCLSID%E3%80%8D%EF%BC%88GUID%EF%BC%89%E3%81%A8
 
属性でVisual Studioにヒントを与える
http://tech.junax.jp/custom-control-medium/wfcm-attribute-category/
 
 
 
開発マシン以外で実行するときは登録が必要ですが、
これがうまくいかない場合があります。
その際は下記が参考になかかもしれません。
http://www.moug.net/faq/viewtopic.php?t=77200
 

トピックに返信