2023年12月13日水曜日

excelのWORKDAY関数を使いこなすまでのお話

 excelのWORKDAY関数で前営業日(前の平日)を求める場合、WORKDAY(開始日+1,-1,祝日)とする。
 開始日+1-1で開始日となり、日数に-1とすることで、前営業日(前の平日)が求まる。
 excelのWORKDAY関数で翌営業日(後の平日)を求める場合、WORKDAY(開始日-1,1,祝日)とする。
 開始日-1+1で開始日となり、日数に1とすることで、翌営業日(後の平日)が求まる。
 なお、excelのWORKDAY関数の日数には0を指定することができない。0を指定すると正しく、営業日を得ることができない。

2023年11月27日月曜日

accessのクエリで特定の文字列を含むか否かで、例えば分類という列にその区別を示す文字列を設定する方法

 accessのクエリで値に応じて、特定の文字列、例えば分類を示すコードを設定した列を作りたい。どうすればいいのか?
例えば、商品名というフィールドに「特別」という文字列が含まれている場合は、分類に「特別」を、そうでなければ「普通」を設定するケースを考えてみる。
新しい列のフィールド名に分類:IIF([商品名] like "*特別*","特別",”普通") と書けばよい。
IIFという関数は、フィールドの値を判定し、TrueかFalseかで処理を分けることができるのだ。
 このIIFの書き方を覚えると、色々と応用できるはずだ。
分類:IIF([商品名] like "*特別*","特別",IIF([商品名] like "*限定*","限定",”普通"))とすれば、限定という分類を簡単に増やすことができる。かっこの数に注意が必要だ。
 歳をとると、こんなテクニックが簡単に出てこなくなる。そのためのメモだ。

2023年8月4日金曜日

vba 入力規則ーリストを最大行まで設定する。

vba 入力規則ーリストを設定する。

Sub SetupLISTBOX()
Dim maxRow As Long
    maxRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp) 'A列で最大行を求める場合
    With Range("C2:C" maxRow).Validation
        .Delete
        .Add Type:=xlValidateWholeNumber, _
             Operator:=xlBetween, _
             Formula1:="=Sheet2!$A$2:$A$100"   ’Sheet2にリストの要素あり
    End With
End Sub

2023年7月26日水曜日

ある日、Windowsパソコンを共有することになり、一番困ったのは、無人運転の夜間バッチや早朝バッチがうまく動かなかった場合のトラシューが難しくなったことだ。

或る日、突然、Windowsパソコンを共有することになった。
これまでは、夜間や早朝に無人運転していたバッチは、ログインしたままなので、エラーが起きた場合、その画面を見ることができた。
しかし、共有することになって、以降は、当然、ログインしたままにできない。
つまり、バッチは、ログインしていなくても実行できるようにした。そして、実行できた。
エラーが起きたら、プログラムはそのエラー画面を出したまま、止まっていた。だから、そのエラー画面を見ることができたのだった。
ところが、バッチで動かしたaccess、excelといったプログラムは、ログインしていないため(システムが動かしているため)、エラーが起こった場合にその画面を見ることができない。
すなわち、表からは見えないシステムの空間で実行されるので、実行中の画面もエラーで止まっている画面も全く見ることができないのである。
どうするかといえば、エラーの原因解明のための情報をログとして吐き出し、プログラムをキチンと終わらせておく必要がある。
つまり、On Error GoTo Error_Handlerをモジュールの先頭で宣言し、エラーの原因究明のじょうほうをログとして出力する、適切なError_Handler(msgbox)を書いておく。 或いは、システムが起動したプログラムを捕まえる方法は、あるのだろうか?

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指定は、効かないのであった。チャンちゃん

2023年2月22日水曜日

vbaの.pasteが実行時エラー5097の問題が発生で止まった。どうすればいいのか?

vba paste 実行時エラー 5097でググってみると、クリップボードへのコピーが完了していないのに、pasteを試みたためらしい。
 application waitで3秒待つコードを追加してみた。これで、暫く、様子を見る。

2023年1月19日木曜日

これまで快調に動いていたexcel vbaのコードが突然、コケる(ABEND:ABnormalENDつまり、異常終了)ようになった。その原因を突き止めるまでのお話である。

 結論を先に言うと、原因は、ファイルの有無を調べるための1回目のdir(パス¥ファイル)がNullにもかかわらず、無謀に2回目のdir()を出していたため。
 だから、修正方法は、1回目のdirがNullの場合、2回目のdirは出さないようにしただけ。
 ワタシのvbaコードは、名前に日付があるファイル名の最大のものを探すと言う関数(FUNCTION)だった。1回目のdirがNullの場合、該当ファイルなしで復帰(exit)するべきところ、あるはずもない最大のもを求め、2回目のdirを出してしまった。この2回目のdirがコケていた訳だ。要するに、該当するファイルが一つもないケースを考慮していなかったのが敗因である。無謀な2回目のdirを出してしまっていた。
 EXCELが突然、コケたののに、このバグをいかに攻略したか?
 デバッグのコツは、自分のコードをじっくりと眺めることである。
ググっても自分のケースにフィットしたトラブル事例がない場合、もう自分のコードに向き合うしかない。
 そして、あるとき、フッと閃く。そう信じて、コードを眺めるしかない。