或る日、突然、Windowsパソコンを共有することになった。 これまでは、夜間や早朝に無人運転していたバッチは、ログインしたままなので、エラーが起きた場合、その画面を見ることができた。 しかし、共有することになって、以降は、当然、ログインしたままにできない。 つまり、バッチは、ログインしていなくても実行できるようにした。そして、実行できた。 エラーが起きたら、プログラムはそのエラー画面を出したまま、止まっていた。だから、そのエラー画面を見ることができたのだった。 ところが、バッチで動かしたaccess、excelといったプログラムは、ログインしていないため(システムが動かしているため)、エラーが起こった場合にその画面を見ることができない。 すなわち、表からは見えないシステムの空間で実行されるので、実行中の画面もエラーで止まっている画面も全く見ることができないのである。 どうするかといえば、エラーの原因解明のための情報をログとして吐き出し、プログラムをキチンと終わらせておく必要がある。 つまり、On Error GoTo Error_Handlerをモジュールの先頭で宣言し、エラーの原因究明のじょうほうをログとして出力する、適切なError_Handler(msgbox)を書いておく。 或いは、システムが起動したプログラムを捕まえる方法は、あるのだろうか?
2023年7月26日水曜日
2023年7月11日火曜日
vbaでシートをコピーし、名前を付けて保存するコードを書くためには、excelの微妙な癖を踏まえる必要がある。それが流儀だ。
vbaでシートをコピーし、名前を付けて保存するコードは、excelのクセを踏まえた上で、コードを書いていく。
Sub CopyandSaveFile()
Dim file1 as String
'menuシートのBxxセルにあるファイル名をゲットしておく。
file1 = Worksheets("menu").Range("Bxx").Value
'まず、新しいブックを作成する。即ち、新しいファイルをオープンしておく。
Workbooks.add
'シートをコピーする。
Worksheet("table").Range("A1:G4").Copy
'シートを貼り付ける。
ActiveSheet.Range("A1:G4").PasteSpecialAll
'式を値にする。
ActiveSheet.Range("A2:G4").Value = ActiveSheet.Range("A2:G4").Value
'列幅を整える。
ActiveSheet.Range("A:G").Autofit
'名前を付けて保存する。
ActiveWorkbook.Saveas fileNmaes:=file1
'ファイルをクローズする。
ActiveWorkbook.Close
end Sub
Workbooks.addしたら、ActiveSheetは、新たに作成した空のファイルのシートになる。それがExcelの癖。そして、最後にファイルをクローズしておくのもexcelの癖に合わせるためだ。
2023年6月30日金曜日
excel vbaでシートの列に引用符付きの式を入れるためのコードでは、引用符をダブルで書けば良い。
excelでは引用符は文字列を設定するために用いられる。 例えば、B列とC烈とD列をハイフン("-")で連結するのであれば、=B2&"-"&C2&"-"&D2となる。ここで&と文字列を挟む引用符(")が重要な役割を果たす。 この式をvbaでA列に設定するコードは、以下の通り。なお、最大行はB列で求めている。
Dim i As Long
Dim maxRow As Long
maxRow = Worksheets("data").Cells(Rows.Count, 2).End(xlUp).Row
For i = 1 to maxRow
Range("A"&i).Formula = "=B" & i & "&""-""&C" & i & "&""-""&D" & i
Next
つまり、式のなかの引用符はダブルで記述する必要があるのだ。
そして、上記のようなやり方で、複数の列でユニークな値を生成し、VLOOKUPでピックアップできるようにするのである。
2023年6月21日水曜日
vbaでメールを操作するときはoutlookを事前に起動していないと例えば、GetInspector.WordEditorが実行時エラーになるよ
vbaでメールを操作するときは、outlookを事前に起動しておく。 当然のことですが、意外と忘れて、vbaコードが実行時エラーとなる。昨日は、動いたのに、なんでーと慌てる。 そんな時には、outlookを立ち上げましょう!そしたら、動くかもです。
2023年6月7日水曜日
タスクスケジューラで「ユーザーがログオンしているかどうかにかかわらず実行する」をチェックしたのに、バッチが起動されないのを解決するまでのストーリー
ログインしたままだと、動いていた夜間バッチは、必ず、一旦、ログオフする運用に変わると、そのままでは起動されなくなってしまった。さて、どうする?
タスクスケジューラのバッチ設定で、まずは、「ユーザーがログオンしているかどうかにかかわらず実行する」をチェックしてみた。でも、これだけでは、起動されなかった。
次に、ぐぐると、開始オプションにそのバッチがあるフォルダを作業フォルダとして指定せよとあったので、そうしたのだが、それでも、なお、起動されなかった。
そして、再びググり、「最上位の特権で実行する」もチェックしたが、駄目だった。
そこで、試しに、コマンドプロンプトで、そのバッチを動かしてみた。そしたら、動かそうとした実行ファイルが、他のプロセスで使用中と怒られた。
なので、タスクスケジューラで、該当のバッチの右クリックし、実行中のインスタンスを全て停止してみた。
そしたら、バッチは、ログインしていなくても動作するようになった。
いろいろ試行錯誤したせいで、インスタンスが宙に浮いてたんだね。
ま Windowsは、色々とわかりにくいね。やれやれ。
2023年5月3日水曜日
excel vbaでメール本文を作るがファイル参照のハイパーリンクがうまくできない場合、"<file://〜>"で挟め。
excel vbaでメール本文を作るがファイル参照のハイパーリンクがうまくできない場合、"<file://〜>"で挟め。
2023年3月3日金曜日
dosバッチで、start /wait anything.accdbでACCESSの処理終了を待合わせできないのは、既に他のaccessが動いていたためであった。
windows7のdosバッチで、start /wait anything.accdbでACCESSの処理終了を待合わせできない、つまり、start /waitが効かないのは、既に他のaccessが動いていたためであった。 この事実に偶然、気付いたのは、これまで同じことをした時には、たまたま(自分以外のaccessが存在しない、唯一のaccessであったため)うまく動いていたからだ。何故、待ち合わせができずに、処理の追い越しが起きたのか?ググってみると、/waitではなぜか、同期が取れないことがあるという記述が出てきたからだ。 そこで、もしかして、accessが起動されている場合と、そうでない場合で、/waitが効かない、効くの差が出てくるのではと、思いついたのだ。 早速、試してみたら、その通り、accessが既に起動されていると、start /wait anything.accdbの完了を待つ/wait指定は、効かないのであった。チャンちゃん