ExcelでSQLを使う

エクセルでSQLを使う必須の関数を紹介しします。

ExcelでSQLを使う-023: ソース公開-07 ELookup関数(Excel To Excel)

 

 

生後14日目。移行期を迎えて2日目。

産室を全体で2畳の広さに拡張。

仔犬たちは、産箱を出て動き回り始めました。

排泄場と産箱との間にある段差も越えて行き来しています。

 

◇◇◇◇◇

 

7、行データを検索・参照するELookup関数

 

 ELookup関数は、次の次の次ぐらいに紹介するDSelect関数とDLookup関数の中間に位置するもので、一行全体のデータを”;”等の区切り子で連結して戻します

 

 

 例えば、DLookup関数は、英語最高得点者である林悟君の<名前><読み><成績>のデータを一度に取得することはできません。その難点をカバーしたのが ELookup関数です。

 

 

 


 

<成績表>と<生徒名簿>の二つの表から検索する

 

 これまでは一つの表からだけ検索していましたが、SQLは複数の表から一度に検索することもできます。N5では、<成績表>と<生徒名簿>から検索しています。


 SELECT 

          [生徒名簿$A1:C100].,  ←不要!
   [生徒名簿$A1:C100].名前,
   [生徒名簿$A1:C100].読み,
   [成績表$D3:I100].成績 
 FROM [生徒名簿$A1:C100], [成績表$D3:I100]
 WHERE
   [成績表$D3:I100].生徒_№=[生徒名簿$A1:C100].№ AND
   [成績表$D3:I100].種類='期末試験' AND
   [成績表$D3:I100].科目_№=1
 ORDER BY [成績表$D3:I100].成績 DESC


 このレベルになるとエクセル初心者がエクセルの式を書いて複数の表から区切り子で連結して検索結果を取得するってのは相当に難しいと思われます。それを、いとも簡単に実現してくれるのがELookup関数です。


 なお、ELookup関数は、予定にはなかったそれです。複数の表から・・・という課題をクリアする上で必要に迫られて昨日に書いたものです。次は、そのソースコードです。まあ、昨日に書いたと言っても、DLookup関数と違うのは朱記している3行程度です。

 

ELookup関数


 Public Function ELookup(ByVal strSQL As String, _
                         Optional ByVal intSearch As Integer = 1, _
                         Optional ByVal xlFileName As String = "", _
                         Optional ByVal isHeader As Boolean = True, _
                         Optional ByVal returnValue As Variant = "") As Variant
 On Error GoTo Err_ELookup
     '
     ' 【要参照設定】
     '
     ' Micrsoft ActiveX Data Objects 2.8 Library
     '

     Dim R       As Integer ' 行インデックス
     Dim N       As Integer ' 行総数 - 1
     Dim cnn     As ADODB.Connection
     Dim rst     As ADODB.Recordset
     Dim fld     As ADODB.Field
     Dim strHDR  As String
     Dim strList As String
  
     Set cnn = New ADODB.Connection
     Set rst = New ADODB.Recordset
     '
     ' ThisWorkbook.FullName の指定
     '
     If Len(xlFileName) = 0 Then
         xlFileName = ThisWorkbook.FullName
     End If
     '
     ' 接続設定
     '

     With cnn
         strHDR = IIf(isHeader, "HDR=YES", "HDR=NO")
         .Provider = "Microsoft.ACE.OLEDB.12.0"
         .Properties("Extended Properties") = "Excel 12.0;" & strHDR & "IMEX=1;"
         .Open xlFileName
         '
         ' 列を読み込み
         '

         With rst
             .Open strSQL, cnn, adOpenKeyset, adLockReadOnly
            If intSearch < 0 Then
                intSearch = rst.RecordCount + intSearch + 1
            End If
            If Not .BOF Then
                 N = CInt(.RecordCount) - 1
                 intSearch = intSearch - 1
                 .MoveFirst
                 For R = 0 To N
                     If intSearch = R Then
                         For Each fld In .Fields
                             strList = strList & fld.Value & ";"
                         Next fld

                         Exit For
                     End If
                     .MoveNext
                 Next R
             End If
         End With
         '
         ' 末尾の";"を消す
         '

         strList = Replace(strList & "[END]", ";[END]", "")
      End With
 Exit_ELookup:
 On Error Resume Next
     rst.Close
     Set rst = Nothing
     ELookup = IIf(Len(strList & "") > 0, strList, returnValue)
     Exit Function
 Err_ELookup:
     If isEcho Then
         MsgBox "SELECT 文の実行時にエラーが発生しました。(ELookup)" & Chr(13) & Chr(13) & _
                 "・Err.Description=" & Err.Description & Chr(13) & _
                 "・SQL Text=" & strSQL, _
                 vbExclamation, " 関数エラーメッセージ"
         Resume Exit_ELookup
     End If
 End Function

 

 Public Function CutStr(ByVal Text As String, _
           ByVal Separator As String, _
           ByVal N As Integer) As String
 Dim strDatas() As String
  If N > 0 Then
   strDatas = Split("" & Separator & Text, Separator, , 0)
   CutStr = strDatas(N * Abs(N <= UBound(strDatas)))
  End If
 End Function

 

 次は、エクセルの表情報を取得するGetFieldInfo関数を紹介します。表情報とは、ADOが表を読み込んだ場合の<列名>と<データの型>に関する情報を指します。これを知ることで、DSelect関数が検索したデータをエクセルのシートに書き出すことができます。

 

PS、エラー制御

 

 DLookup関数、Elookup関数、DSelect関数を式に組み込んだ時は、広域変数 isEcho を真にしておくと、関連データを削除した際にエラーが表示されます。それが煩わしいので既定では、その値を偽にしていまっす。以下は、その真と偽とを切り替えるマクロです。

Sub SQLツールのエラー制御()
  isEcho = Not isEcho
  If isEcho Then
    Message "SQLツールのエラーを常に表示します。"
  Else
    Message "SQLツールのエラーの表示を停止しました。"
  End If
End Sub