2022年11月22日火曜日

Excel vbaで「1004 rangeクラスのautofilterメソッドが失敗しました」と怒られ、試行錯誤で辿り着いた原因。

Range("A1").Autofilter n,Array("○","×"),xlFilterValuesでフィルターをかけた。
 そしたら、「1004 rangeクラスのautofilterメソッドが失敗しました」というエラーが出た。
 色々と試したとこと、どうやら、A列からn番目の列の領域(current region)に切れ目(空白のセル、特にタイトル行の空白ありがよくあるパターン)があるとこのエラーが出るようだ。
 このエラーを回避するためには、ブランクのセルに何らかの値を入れるといいようだ。
 例えば、少なくとも1行目のタイトル行には何らかのタイトル(項目名)を入れておく。
 ここで、突然ですが、自分へのメモ。ステーキのたれのレシピです。醤油2に対して、日本酒1、みりん1。これに、ニンニクのローストが欠かせない。付け合わせは、ポテサラかな。そして、上質な赤ワイン。パンチがあるカバネー(Cabernet)がいい。

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