2025年4月17日木曜日

ACCESSを起動してパラメタ /x "macro-name"で起動すると/xで指定したマクロを動かせるということに気がつくまでの話

 結論を先に言うと、ACCESSに/x "マクロ名"という起動パラメタをつけて起動すると、ACCESSが立ち上がった直後にファイルに/xで指定したマクロを動かすことができる。
 例えば、バッチファイルで、start c:¥users¥username¥documents¥xxxxx.accdb /x "macro-name"でACCESSを起動すると/x "macro-name"で指定したマクロが動くわけだ。  これは、Office 起動 スイッチでググり、ACCESSの起動スイッチの/xの説明に詳しく書いてある。
 ちなみにマクロ名をAutoExecにすると、/x AutoExecを付けなくてもACCESSを起動すると、AutoExecというマクロが動くのである。

ACCESSの起動スイッチ
 /x スイッチの前に指定した Access データベースを開いてから、指定したマクロを実行します。 データベースを開いたときにマクロを実行する別の方法は、AutoExec という名前のマクロを作成することです。
 マクロにはウイルスが含まれている可能性があるため、実行には注意が必要です。 実行する場合は、コンピューターで最新のウイルス対策ソフトウェアを実行する、セキュリティ センターを使用して、すべてのマクロ (デジタル署名されているものを除く) を無効にする、マクロの信頼できるソースのリストを保持するという予防策を講じてください。
 まず、マイクロソフトでは起動パラメタではなく、スイッチと呼んでいるので、ググりかたを「こむづかしく」している。なかなか先程のページに辿り着けない。
 どうすれば、ACCESSのマクロを起動時に呼び出せるのかが分かりにくいのだ。

2025年4月13日日曜日

スマホで見ると文字がはみ出していたhtmlをはみ出さないようにしてみた。preタグのstyleでoverflow: auto;を指定すればOKだ。

prettycodeを使わずにソースコードを格好良くしたのに、スマホで見ると文字がはみ出していたので、htmlを手直しして、はみ出さないようにしてみた。preタグのstyleでoverflow: auto;を指定すればOKだ。

2025年4月9日水曜日

prettyprintみたいな見た目をhtmlで描いてみた。pタグにstyle="background-color:black;border-radius: 7px 7px 7px 7px;"><font color="yellow">のように追加すれば良い。、

いつもはprettyprintのお世話になってるが、htmlのみでそれらしくしてみた。
pタグにstyle="background-color:black;border-radius: 7px 7px 7px 7px;"><font color="yellow">のように追加すれば、黒背景に黄色い文字でソースコードっぽく表示させことができる。実際のページは、これだ。

Public Function AutoStartProc() If InStr(Command,"Delete")>0 then DoCmd.SetWarnings False Docmd.OpenQuery "DeleteTableA" '2GB超えの要因となっている不要なテーブルTableAを削除しておく。 DoCmd.SetWarnings True Application.Quit  ’オプションの□ 閉じると最適化するにチェックを入れておく。この結果、最適化が走る。 ElseIf InStr(Command,"afterDelete")>0 then 最適化後にやりたい処理 Docmd.SetWarning False Docmd.OpenQuery "QueryA" Docmd.SetWarngs True Aoplication.Quit End If End Function

そのhtmlソースコードは、以下の通り。
<p> <pre><code><p style="background-color:black;border-radius: 7px 7px 7px 7px;overflow: auto;"><font color="yellow"> Public Function AutoStartProc() If InStr(Command,"Delete")>0 then DoCmd.SetWarnings False Docmd.OpenQuery "DeleteTableA" '2GB超えの要因となっている不要なテーブルTableAを削除しておく。 DoCmd.SetWarnings True Application.Quit  ’オプションの□ 閉じると最適化するにチェックを入れておく。この結果、最適化が走る。 ElseIf InStr(Command,"afterDelete")>0 then 最適化後にやりたい処理 Docmd.SetWarning False Docmd.OpenQuery "QueryA" Docmd.SetWarngs True Aoplication.Quit End If End Function</br> </font></p></code></pre>

ポイントは、pタグにstyleで黒背景のbackground-color:black;と角丸のorder-radius: 7px 7px 7px 7px;overflow: auto;を指定し、フォントの文字色はyellowにするだけだ。

2025年4月7日月曜日

2GBの壁ギリギリでaCceSSを使いこなす。そのやり方はこうだ。

 acccessには2GBの壁がある。不要なテーブルをその都度削除しつつ、この壁ギリギリで使いこなすということもままある。
そういうケースで再び立ちはだかるのが、「accessの最適化はaccessを閉じる時しか出来ない」ということだ。aCCessを開いたままで最適化できると楽チンなのですが、それは出来ない。
 2GBが超えが起きるたびに手動で不要なテーブルを削除すればいいのだが、効率が悪い。とりわけ自動化したい場合にはマズイ。
そこで、起動パラメタを見て不要なテーブルを削除し、終了するようにする。
あらかじめ、終了時に最適化が走るようにaccessのオプションの「□ 閉じると最適化する」にチェックを入れておく必要がある。
以下のコードを標準モジュールに記述しておく。そして、accessのAutoExecマクロを登録し、AutoStartProcを呼び出すようにしておく。
 起動パラメタは、/cmd 起動パラメタでbatファイルに記述しておけば、VBAではCommandという変数で受け取ることができる。

Public Function AutoStartProc() If InStr(Command,"Delete")>0 then DoCmd.SetWarnings False Docmd.OpenQuery "DeleteTableA" '2GB超えの要因となっている不要なテーブルTableAを削除しておく。 DoCmd.SetWarnings True Application.Quit  ’オプションの□ 閉じると最適化するにチェックを入れておく。この結果、最適化が走る。 ElseIf InStr(Command,"afterDelete")>0 then 最適化後にやりたい処理 Docmd.SetWarning False Docmd.OpenQuery "QueryA" Docmd.SetWarngs True Aoplication.Quit End If End Function

そして、バッチファイル(x.bat)は以下のようにを書けば良い。

start  /wait abc.accdb /cmd  "Delete" start  /wait abc.accdb /cmd  "afterDelete"

バッチファイルを作らず、タスクスケジューラの基本タスクで実現する場合、プログラム/スクリプトと引数にそれぞれ、aCCessのフルパス、自分のaCCessファイルのフルパス /cmd "Delete"と指定した基本タスク(テーブルを削除し、最適化を行う)と、引数に自分のaCCessファイルのフルパス /cmd "afterDelete"を指定した基本タスク(最適化後にやりたい処理 )を用意しても良い。

2025年4月5日土曜日

accessのODBC接続でSQLサーバからデータ取得するときにVBAでログインのコードは要らなかった。5年後に分かった。

 この記事は、5年前に書いたのだが、実は、このログイン画面を出さないためのvbaのコードは全く不要だった。  実は、ODBC接続のテーブルをインポートする際、「ユーザIDとパスワードを保存する」というチェックボックスが出てくるので、そこにチェックを入れておくだけで良かったのである。 5年間も気が付かなかった。あーそれそれ。おーそれそれ。いやはや、なんとも言えない。灯台もと暮らし。
 accessのODBC接続でSQLサーバからデータ取得するときに、SQLサーバの参照の度にログイン画面がでてくのは、ウザイ。VBAでログイン処理を書いて自動化したい。つまり、ログイン画面をポップアップさせずに、VBAでODBCでSQLサーバにログインし、データを取って来たいのだ。  よくあるやりかたとしては、ADOコネクションを生成し、DB接続情報をセット(ODBC)、接続をOpenするというrecordsetでデータを取得するというアプローチで、1レコードずつ処理することになるので、面倒くさい。
  1. Set objConn = CreateObject("ADO.Connection")
  2. objConn.ConnectionString = "DSN=DSN1;UID=user1;PWD=password1;"
  3. objConn.Open
 SQLサーバのテーブルをリンクした、選択クエリを作成している場合、SQLサーバのテーブルへアクセスするのにログイン画面がでてくる。 そのログイン画面を出さないためには、Docmdを使った「簡単な」方法があるのだ。 以下のコードを標準モジュールのどこかに記述してやる。
  1. DoCmd.DeleteObject  Actable,"dbo_TBL-A"
  2. DoCmd.TransferDatabase acLInk,"ODBC Database", _
  3.  "ODBC;DSN=dsn_name;UID=user_id;PWD=pass_wd; _
  4.  & "DATABASE= database_name",acTable,"tabl_name","dbo.tbl_name"
 このテクニックのミソは、TransferDatabaseでSQLサーバのテーブルへのリンクをログイン画面をださすに接続できる、つまり、自動的にコード内で密かにログインしているところだ。そのためにTransferDatabase acLInkの後ろにDB接続情報を記述している。そこがミソなのだ。ちなみにこの文字列はACCESSのリンクテーブルにカーソルを持っていくと、ヌッと表示されるのだ。試してもらいたい。  そして、SQLのテーブルを参照した選択クエリを実行し、EXCELにエクスポートするという2つの操作を1つのDocmdで実現できてしまうのだ。実に効率がいいね。
Dim file1 As String
Docmd TransferSpreadsheet acExport,acSpreadsheetTypeExcel12Xmi,"SELECT_QUERY_USING_SQLserversTable",file1,True

2025年3月26日水曜日

vbaで名前を付けて保存というタイトル名のウィンドウを捕まえて、任意の場所にファイルを保存する

vbaで「名前を付けて保存」というタイトルのウィンドウを捕まえるには、AppActivate "名前を付けて保存"と書く。
そして、保存先を自由に設定するには、フルパスのファイル名で保存すれば良いのである。

SendKeysとAppActivateの組み合わせでRPAを実現してみたが、マウスカーソルを当てないと動かせないアプリがいる。

マウスのカーソル(矢印)を当てなくても、TABキーやENTERキーを叩けば動くアプリは、SendKeysで自動運転することができる。
しかしながら、マウスのカーソル(矢印)を当てないと動かないアプリがある。
そういう場合には、WindowsAPIのSetCursorPos関数とmouse_event関数をつかう。
厄介なのは、マウスのカーソルの座標をどうやって取得するかである。
Windowsアクセサリのペイントは、イメージファイルを開くと、マウスのカーソルの座標を画面左隅に出力してくれる。これを利用してクリックしたいボタンの座標を求めればよい。そこで、まず、クリックしたいアプリの画面をアクティブにして、print screen キーを押下する。そして、ペイントを開いて。その画像をペーストする。次に画像を拡大し、座標を調べたい場所にカーソルを合わせる。すると、ペイントの画面左隅にX座標とY座標を表示されるのである。

2025年2月18日火曜日

dosバッチのログはcmd >> log.txt 2>&1でexcel vbaツールのログはdebugprintモジュールで取得する。

dosバッチのログはcmd >> log.txt 2>&1でexcel vbaツールのログはdebugprintモジュールで取得する。
ログを取るのは自己防御のためである。正しい処理をしているのか、何かトラブルが発生してから対策するのではなく、日頃から自分が何をしたかトレースできる仕組みを構築しておくことが肝要である。
excel vbaの場合、application.statusbar="文字列"でツール画面の左下隅に進行状況を知らせる文字列を出力する。内部トレースのルーチンを作り、そのトレース情報をツールと同じフォルダのdebugprint.txtに出しつつ、application.statusbar=にも設定し、ツール画面の左下隅に出すのも面白いかもしれない。

2025年2月13日木曜日

昔はdir("*.xls*")でxlsやxlsxやxlsmも検出できたと記憶している。ところが今はdir("*.xlsx*")と書かないとxlsに加えてxlsxを検出できない。本当かな?

昔はdir("*.xls*")でxlsやxlsxやxlsmも検出できたと記憶している。ところが今はdir("*.xlsx*")と書かないとxlsに加えてxlsxを検出できない。本当かな?

2025年1月30日木曜日

vbaでAppActivate [title]とSendKeys {TAB} or {ENTER}等々で基幹システムへのログイン、検索といった様々な画面の操作を簡単に自在に操る。

SendKeysとAppActivateの組み合わせでRPAを実現してみた。ポイントは{TAB}と{ENTER}だ。{TAB}や{矢印キー}でカーソルを移動させ、{ENTER}でボタンを押下すれば良いのだ。そして、表示が出てくるのを待つのはApplication.Waitが簡単だが、WindowAPIで画面のボタンのハンドルIDをゲットし、ボタンの状態(アクティブか否か)を得ることができれば、確実に画面表示を待つことができる。

  • まず、AppActivate [title(画面タイトル)]で操作したい画面を捕まえる。
    AppActivate "ログイン"
  • そして、SendKeys {TAB}を繰り返し、目的の場所へカーソルを動かす。
    SendKeys (TAB 2] ・・・2回タブ
  • さらに、SendKeys nn(数値)で設定したい値にする。
    SendKeys ID001でロウインIDを設定する。
  • ふたたびSendKey {TAB}を繰り返し、実行ボタンに辿り着く。
    SendKeys 1234でパスワードを設定する。
  • そして、SendKeys {ENTER}で実行ボタンをクリックする。
    SendKeys {ENTER}でログインボタンをクリックする。
  • 検索のボタンをクリックした後、検索結果の画面が表示されるのを待つには、Application.Waitを使うのが一番、簡単である。Application.Wait Now() + TimeValue("00:00:03")と書くと、3秒待つことができる。
  • windowsAPIの関数を駆使し、検索のボタンのハンドルIDを探すと、確実にボタンの操作することができる。
  • また、検索結果の表示ボタンのハンドルIDが取得できれば、そのボタンがアクティブか否かを検出することで、検索結果の画面を待つことができる。

    以上のようなことをvbaのモジュールに記述すればよい。時々、Appactvateで操作したい画面が捕まらないとか、不可解な現象が発生することがあるので、過信は禁物だ。たまに動かないことがあるので、確認しながら使うのが宜しいと思う。

2025年1月22日水曜日

vba application.FileDialogでフォルダを設定する

menuシートのB5セルにファイルせんたくのダイアログを使用して、出力用のフォルダを設定する。

Sub SetFolder()
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            Worksheets("menu").Range("B5") = .SelectedItems(1)
        End If
    End With
End Sub

2025年1月14日火曜日

達人の「うどん」レシピ

 達人のうどんレシピは、12%の塩水でコネて、ひと晩寝かせる。
 分量をきちんと守る。これが鉄則だ。
 作り方は、以下のとおりだ。
 材料を揃えたら、全部、混ぜる。こねて、ひとつの玉(団子)にまとめる。ビニール袋(ジップロック)に入れて、新聞紙の上に置く。タオルを被せて、100回足で踏め。ビニール袋から取り出して、ひとつの玉にして、袋に戻す。タオルをかけて100回踏む。これをもう8回繰り返せ。つまり、1000回踏む事になる。タオルに巻いてひと晩寝かせよ。翌朝、取り出し、綿棒で伸ばせ。好みの太さで切れ。たっぷりのお湯で茹でよ。10分ぐらいかな。麺つゆを好みの濃さにお湯で薄めて、ネギに生姜、七味を加えて、茹でたうどんを浸して啜れ。旨いぞ、釜揚げうどんだ。

  • 水 86g 塩 10g
  • 強力粉 120g 薄力粉 80g