Range("A1").Autofilter n,Array("○","×"),xlFilterValuesでフィルターをかけた。 そしたら、「1004 rangeクラスのautofilterメソッドが失敗しました」というエラーが出た。 色々と試したとこと、どうやら、A列からn番目の列の領域(current region)に切れ目(空白のセル、特にタイトル行の空白ありがよくあるパターン)があるとこのエラーが出るようだ。 このエラーを回避するためには、ブランクのセルに何らかの値を入れるといいようだ。 例えば、少なくとも1行目のタイトル行には何らかのタイトル(項目名)を入れておく。 ここで、突然ですが、自分へのメモ。ステーキのたれのレシピです。醤油2に対して、日本酒1、みりん1。これに、ニンニクのローストが欠かせない。付け合わせは、ポテサラかな。そして、上質な赤ワイン。パンチがあるカバネー(Cabernet)がいい。
2022年11月22日火曜日
2022年11月17日木曜日
EXCEL vbaでwhereのnoをIN+配列+joinで複数指定するのではなく、noをひとつ指定したSELECT を必要な分だけ繰り返し発行する。
EXCEL vbaでwhereのnoをIN+配列+joinで複数指定して、SQLを1回で済ませると手っ取り早いが、SQL文の最大文字数(バッチサイズ)65536バイト以内にする必要がある。 そこで、noをひとつ指定したSELECT を必要な分だけ繰り返し発行する。 ActiveWorkbook.Worksheets(1)のA列にNOが入っていると仮定する。これでどうじゃろかな?
Dim i As Long
Dim noStr as String
Dim strSQL as String
Dim maxRow as Long
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Private Const PROVIDER As String = "SQLOLEDB"
Private Const DATA_SOURCE As String = "localhost" 'サーバ名
Private Const DATABASE As String = "dbname" 'データベース名
Private Const USER_ID As String = "UID=user" 'ユーザID
Private Const PASSWORD As String = "password" 'ユーザパスワード
'SQL Server認証で接続する場合
cn.ConnectionString = "Provider=" & PROVIDER _
& ";Data Source=" & DATA_SOURCE _
& ";Initial Catalog=" & DATABASE _
& ";UID=" & USER_ID _
& ";PWD=" & PASSWORD
cn.Open
maxRow = ActiveWorkbook.Worksheets(1).Cells(Rows.Count,1).End(xlUp).Row
For i = 2 to maxRow
nostr = activeWorkbook.WorkSheet(1).Cells(i,1).Value
strSQL = SELECT * from TBL_A A inner join TBL_B B on A.[NO] B.[NO] where A.[NO] IN (" & noStr & ") AND B.[TYPE] = 1;"
rs.Open strSQL, cn
rs.MoveFirst
ActiveSheet.Range("A1").CopyFromRecordset rs
If Not rs Is Nothing Then
If rs.State = adStateOpen Then rs.Close
Set rs = Nothing
End If
Next
If Not cn Is Nothing Then
If cn.State = adStateOpen Then cn.Close
Set cn = Nothing
End If
End Sub
2022年11月6日日曜日
EXCEL vbaでSELECT文のwhere句をIN+配列+join関数で作る。
SELECT文のwhere句のINを複数指定する場合、INの中身を配列とjoinで作る事になる。その例をぐぐっても出てこなかったので、やむを得ず作ってみた。 ActiveWorkbook.Worksheets(1)のA列にNOが入っていると仮定する。これでどうじゃろかな?
Dim i As Long
Dim noStr as String
Dim strSQL as String
Dim noArr as variant
Dim maxRow as Long
maxRow = ActiveWorkbook.Worksheets(1).Cells(Rows.Count,1).End(xlUp).Row
reDim noArr(maxRow)
For i = 2 to maxRow
noArr(i-2) = Cells(i,1) '1次元配列に入れる
Next
noStr = join(noArr,",")
strSQL = SELECT * from TBL_A A inner join TBL_B B on A.[NO] B.[NO] where A.[NO] IN (" & noStr & ") AND B.[TYPE] = 1;"
2022年11月4日金曜日
sqlのwhereでINとANDを併用してみる。
select A.NO B.NO from A inner join B on A.NO = B.NO where A.NO IN (1,2,3) AND B.TYPE = 9 ;こう書いても良い
select A.NO B.NO from A inner join B on A.NO = B.NO where (A.NO,B.TYPE) IN ((1,9),(2,9)(3,9)) ;
vbaのjoinで一次元配列をカンマ区切りの文字列にする。
Dim myArray as variant myArray = array(1,2,3,4,5) myArrayStr = join ( myArray,",") ' myArrayStr = 1,2,3,4,5
2022年10月27日木曜日
access vbaでラジオボタン(オプションボタン)を操る。
入力フォームという名前のフォームにfrmTypeというフレームを追加し、そのフレームに「type1(値1)」と「type2(値2)」というオプションボタンを追加した。 標準モジュールで、オプションボタンを判定するコードは、以下のような感じだ。
If [Forms]![入力フォーム]![frmType].Value = 1 then [type1の処理] else [type2の処理] End If
2022年10月20日木曜日
access vbaで最適化コマンドは開いていると実行できないので、起動パラメタで制御できるようにしてみた。確実に。
access vbaでは、最適化コマンドはdbを開いていると実行できない。 SendKeys "%(YC)"またはSendKeys "%(Y){TAB}{Enter}"で動かせるようだが、SendKeysはキー送信のため、不安定であり、うまく動かないことがある。 確実に最適化を動かすために、起動パラメタを使うのがいい。是非、マネしてください。 起動パラメタは、c:¥Users¥username¥Documents¥abc.accdb /cmd "actParam1"というコマンドラインを叩くと、起動時にactParam1というパラメタをvbaで受け取ることができる。 一方、accessの設定で、閉じると自動的に最適化を行うようにしておく。 以下のモジュールをvbaで書いて、AutoExecという名前のマクロを作成し、AutoStartProcプロシジャを開くように登録しておく。 AutoStartProcの中身は、こんな感じだ。
Public Function AutoStartProc()
If InStr(Command,"actParam1")>0 then
Application.Quit ’オプションの□ 閉じると最適化するにチェックを入れておく。この結果、最適化が走る。
ElseIf InStr(Command,"actParam2")>0 then
[最適化後にやりたい処理]
Docmd.XXXXX
Docmd.YYYYY
Aoplication.Quit
End If
End Function
これで、actParam1という起動パラメタの場合、accessを閉じる(Application.quit)ことで最適化が走るようになる仕掛けが完成する。
そして、start /wait c:¥Users¥username¥Documents¥abc.accdb /cmd "actParam1"で起動すれば、最適化が動く。なお、/waitにより、必ずコマンドの完了を待つことができる。そして、これ(/wait)がとても大切になる。また、不要なオブジェクト、つまり、2GB超えの要因となりそうなテーブルを再作成するケースであれば、再作成の前にこのタイミングで、いったん全てのオブジェクトを一旦、削除して、最適化を走らせておくのがよろしいだろう。
また、start /wait c:¥Users¥username¥Documents¥abc.accdb /cmd "actParam2"で起動すれば、actParam2のアクションを行うことができる。