HTA(HTMLApplication)やりだしたついでに、毎日書いている日報。少し前にリニューアルオープンしたのですが、結構粗造りのままで見にくい&使いにくい。そんなのでもお上が強制するものだから使ってるけど。で、何かあったら送ってくれ。というのはいいけれど、使い勝手が悪いところをあれこれ送ったら、結局(本人は使わないからか)、その要望を満たす気も無く、トラブルじゃないからいいでしょ?だって、
あんたが作ったのは、エラー処理も満足にしてないのに、ユーザーが意図しない操作をしたらそれはユーザーが悪い。ってことにするんでしょう。そういうマクロやソフトをばら撒いて使用を強制してあれダメこれダメ。あなたがこんなことやったのが悪いんでしょ。とかって言うからPCを苦手と思う人が続出するんじゃないの?うちの会社。なじみが無いから苦手。ってのは苦手にさせたやつのいいわけじゃないの?そんな人でも電卓使うんだから、
で、マクロのパスワードを送ってきて、手を加えて作ってみろや!よかったらお上のに取り込んでやるわ。って感じのメールが来た。ムカつくので、こちらから何かすることはしていなかったけど、外部から強制的に動かしてやろうかなっと。
HTAでフォームを作って、主に使う部分、面倒な部分は前もって全部入れておいて、自動化部分が見える状態で且つユーザーがクリックしたりしたのに反応しないようにしておけば、怪しい動きをすることもないですし。
メインで使うのはCreateObject or GetObject。残念ながらファイル名をドラッグアンドドロップでとってくる部分(レジストリいじると可能らしいですが)はVBSに関数作って(VBSファイルにExcelファイルをドロップしてそのファイル名をHTAに渡すという感じです)。あとは普通にExcel操作。もちろんマクロは元々入ってるのをそのまま使うことにします。何をしてるのかわからないもの、とりあえずちゃんと動いているので下手にいじるより、そのまま使い続けるように。Excelたちあげたら、振り分けていろんなシートのセルに値を入れるとか、並べ替えるとかその程度。それでもIMEの制御ぐらいはしますよ。自分用ですが、半角全角キーを押したりなんてことは避けたいですから。
せっかくのHTAなんでHTMLで独り言を書いてみて。なかなかスパイスの効いたのを書けたら、他の方にもゼヒ読んでいただこうと思います。Excel的に簡単にできるのにやってない。ということを白日の下にさらしてみようと思います。
リニューアルオープンしたときに私があれこれコードを書いてそれをコピペしただけなのに、私の協力で。だって、、わからなかったから全面的に教えてもらいましたやろ!と思ったものですが、そこは大人なので私の名前が出てくるなんて思ってもいませんでした、恐悦至極にごじゃりますよぉぉぉと送った覚えがあります。
で、つまずいたところ調べまわったポイント↓↓
1.HTAでファイル名を調べるために(月ごとにファイル名が変わるので)
VBSファイルにD&Dしたファイル名をHTAに引数として渡すため
Set regEx = New RegExp
regEx.Pattern = "ファイル名で特定できる部分.xls" ' 検索文字列を検索パターンとして指定
regEx.Global = True ' 文字列全体を検索するように指定
regEx.IgnoreCase = True ' 大文字・小文字は検索に影響しない
Dim xFilePath
Set objArgs = WScript.Arguments
For I = 0 to objArgs.Count - 1
If regEx.Test(objArgs(I)) Then
' WScript.Echo objArgs(I)
xFilePath=objArgs(I)
end if
Next
ループは元のサンプルにあったのと、間違って全然関係ないファイルをD&Dしたときのため
mypath = Wscript.scriptfullname
lastpos = InStrRev(mypath,"\")
mypath= left(mypath,lastpos)
mypath=mypath & "HTAファイル名.hta"
objShell.Run chr(34) & mypath & chr(34) & "\HTAファイル名l.hta " & chr(34) + xFilePath + chr(34)
とした。
で、HTAファイル側で一番大事なのはExcelの操作をしようとするときは常にExcelが立ち上がっていてHTAから操作できる状態になっているようにすること。そのために、
グローバル変数を宣言しといて(そんなのあるのかわかりませんがちゃんと動いていることを考えたらその役目を果たしてるんでしょうか、それとも全ての変数がグローバルなのでしょうか?ま。それはおいといて)
Sub ExcelChk()
Set myXlsAPP = Nothing
Set myTEST = Nothing
arrCommands = Split(objTestHTA.commandLine, chr(34))
'objTestHTAは<HTA:applicationタグ中idで指定した自分自身を指す。ここで引数をGET
xFilePath= arrCommands(3) 'Hey,Scripting Guyより
'http://oshiete1.goo.ne.jp/kotaeru.php3?q=1314809
'http://www.nurs.or.jp/~ppoy/access/access/acX006.html
'を参考に
Set xls = GetObject(, "Excel.application")
If Err.Number <> 0 Then 'エラーが起こる=エクセルは起動してない
Err.Clear
Set myXlsAPP = CreateObject("Excel.Application")
myXlsAPP.Visible = True
Set myTEST = myXlsAPP.Workbooks.Open(xFilePath)
Else 'エラーが起こっていない=エクセルは起動している
Set myXlsAPP=xls
Dim Stay '開いていてほしいファイルが開いていればStay=1にする
Stay=0
For Each wkb In xls.Workbooks
If wkb.Name = Dir(xFilePath) Then
Set myTEST = wkb
Stay=1
End If
Next
if Stay=0 then 'エクセルは起動しているが目的のファイルは開いてない
Set myTEST = myXlsAPP.Workbooks.Open(xFilePath)
End if
myXlsAPP.Visible=True
End If
End Sub
という関数を作って、Excelへの作業をする前には必ずこれを呼び出して、myXlsAPPとSet myTESTを使える状態にする。
Excel中の操作はやりたいことをマクロ記録して、オブジェクトブラウザ見ながら同じようにしていけば済みますが、
http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list124.shtml に
VBScriptでは、「:=」を使った指定(名前付き引数)は使えません。
この場合、
.Sort Key1:=~, Order1:=xlAscending
の部分は、
.Sort ~, xlAscending
としてください。
それから、『xlAscending』はExcelの定数ですので、
VBScriptでは未定義になっています。事前に
Const xlAscending = 1
などの定数定義を行ってください。
それと、もう一つ。
Range("C2") という表記は、Excel VBA上ならば構いませんが、
外部から制御するときには使えません。(どのシートの範囲かが曖昧なので)ExcelApp.ActiveSheet.Range("C2") などの記述を使いましょう。
というのを見つけたので、関数はExcelのオブジェクトブラウザ見ながら順番に定数で指定しました。起動時用のスクリプトは</head>と<body>の間にSub Window_onLoad という名前で指定できるようです。
結構いろんなところをググッたのですが、それ以外にHey,Scripting Guys日本語(MSのVBS講座でしょうか)がいろんな例が載っていて非常に参考になりました。
HTAもVBSのようにエラー処理がVBAより不便なのでそこらへんはこれからです
全然HTAとは関係ないですが、Ajax を使った 日本語 IME なんかすごいなぁと思ってしまいました。今までIMEってMS-IME、ATOKなど選べても(Javaでは作れるみたいですが)ブラウザ上でこういう感じってなかったように思いました。商品名など入れるときカタカナが多いので、いちいちF7押さなくてもカタカナに変える方法ないかなぁと思っていたので、Ajaxぼちぼち使っていますが、ブラウザ上で画面遷移なしにいろんな処理ができても、世間はあんまり感慨はないんですね。私は結構うれしいんですが。Web経由の常に待ち時間のあったユーザーインターフェースがやっと普通のアプリ並みになった。というところで、驚くことはないんでしょうね
最近のコメント