[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『エクセルとアクセスを活用していたのですが、アクセスが廃止になりました』(あや)
エクセルVBA アクセスクエリ アクセスVBA を使って、集計をしております
今回、アクセスが廃止されることになり 対応方法を考えています (出来る限り現状は変えず回避方向で…)
集計作業の内容 エクセルのデータファイルを、 1エクセル側からアクセスのインポートファンクションを呼び出し 2アクセスVBAでインポート 3アクセスクエリで結合や抽出条件を指定し 必要なデータに成形 4エクセル側からアクセスのエクスポートファンクションを呼び出し 5アクセスVBAでエクセルに出力
(実際の記述) 1エクセル側からアクセスのインポートファンクションを呼び出し
’エクセル モジュールに記述 'Accessにインポート&★チェック.xlsにエクスポート strAccessPath = ThisWorkbook.Path & "\チェック.mdb"
Set objAccess = CreateObject("Access.Application") objAccess.Opencurrentdatabase strAccessPath
objAccess.Run "Fnインポート" objAccess.Run "Fnエクスポート" ☆
objAccess.closecurrentdatabase objAccess.Quit Set objAccess = Nothing
2アクセスVBAでインポート
’アクセスモジュールに記述 Function Fnインポート() On Error GoTo エラー
Dim Active_mdb As String Dim varac As Variant Dim varxls As Variant
Active_mdb = CurrentProject.Path
varac = "tbl_チェック" varxls = Active_mdb & "\チェック.xls"
DoCmd.DeleteObject acTable, varac DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _ varac, varxls, True, "チェック!"
Exit Function
エラー:
MsgBox "予期せぬエラーが発生しました。" & Chr(13) & _ "エラー番号:" & Err.Number & Chr(13) & _ "エラー内容:" & Err.Description, vbCritical End Function
3アクセスクエリで結合や抽出条件を指定し 必要なデータに成形 クエリデザインビューでテーブル結合や抽出条件を指定
4エクセル側からアクセスのエクスポートファンクションを呼び出し (1エクセル側からアクセスのインポートファンクションを呼び出し)の☆部分
5アクセスVBAでエクスポート
Function Fnエクスポート()
On Error GoTo エラー
Dim Active_mdb As String Dim varac As Variant Dim varxls As Variant
Active_mdb = CurrentProject.Path
varxls = Active_mdb & "\★チェック.xls"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, _ "qry_作業1", varxls, True
Exit Function
エラー:
MsgBox "予期せぬエラーが発生しました。" & Chr(13) & _ "エラー番号:" & Err.Number & Chr(13) & _ "エラー内容:" & Err.Description, vbCritical
End Function
(伝わりにくい部分がいくつかあるかと思います…) こんな形でアクセスを使用しているのですが アクセスがなくなることにより、 アクセスのクエリを活用している部分を他の動きで代用する必要があり
クエリを代用するものでわたしが思いつくのは エクセルのVLOOKUPをマクロで再現したり、かなと思いますが たくさんのクエリを使っているため、 良い方法はないかなと考えております
アクセスがなくても、エクセルからデータベースを動かすなど…? 幅広く教えていただけると勉強になります
*説明不足があるかと思いますので、 そのときはご指示下さい
< 使用 Excel:Excel2010、使用 OS:WindowsXP >
しかし、移植にはこれらが仇になってしまうので、新たに標準のSQL文やVBAの処理で作り直すしかないかと思います。
クエリの性能に依存した処理をしているほど、移植は大変になるでしょう。
(移植より、新たな処理を考えたほうが早いかもしれませんね)
VBAでは、ADODB.Connection 等を使用して、MDBだけでなく、シートやCSVをDB扱いすることもできます。
Accessに慣れているのでしたら、集計が必要な場合に、SQL文で処理する方法もありますので、調べてみてください。
(Excel2010のようなので、.Provider = "Microsoft.ACE.OLEDB.12.0" なんかも検索候補に)
(???) 2014/09/03(水) 16:26
>アクセスがなくても、エクセルからデータベースを動かす
あやさんの投稿から、ファイルは、Office2003以前のバージョンで管理されていたものを Excel2010でアクセスなしで管理する ということでしょうか?
よって、同じ仕様をアクセスアプリを使った場合と対比できるようにサンプル仕様を明確にしたいと思います。
仕様は、Excelファイルとmdbファイルでデータのやり取りを行い、結果を新たなExcelファイルに作成する という内容です。
ファイル構成
sample1.xls ----> sample2.xls dbsamp.mdb
VBAsamp.xls ---- VBAコードがあるExcelファイル(サンプルデータ作成コードと仕様実行コード)
sample1.xls Sheet1に以下のようなデータを用意します。
A B C D 1 会員番号 氏名 出身 血液型 2 1 奥田 美香 東京都 A型 3 2 榎田 道子 東京都 AB型 4 3 吉野 佳代子 埼玉県 O型 5 4 新田 恵利 埼玉県 O型 6 5 中島 美春 東京都 A型 7 6 樹原亜紀 神奈川県 AB型 8 7 友田 麻美子 東京都 A型
Dbsamp.mdb
tbl1 というテーブルとqry1というクエリを用意します。
tbl1 は、以下のようなデータを用意します。
会員番号 備考 1 週間文春タバコフォーカス事件にて脱退 2 週間文春タバコフォーカス事件にて脱退 3 週間文春タバコフォーカス事件にて脱退 4 初期メンバーの中で最も活躍。在籍中にボンド/キャニオンからソロデビュー 5 「なかじ」の愛称で親しまれる 6 ニャンギラスの一員として活躍。妙に背が高い 7 週間文春タバコフォーカス事件にて脱退
尚、フィールド構成は、
会員番号 数値型 主キー 備考 テキスト型
なっています。
qry1 内容は、以下のsqlです。
SELECT table1.会員番号, table1.氏名, table1.出身, table1.血液型, tbl1.備考 FROM table1 LEFT JOIN tbl1 ON table1.会員番号 = tbl1.会員番号;
尚、上記のtable1とは、sample1.xlsのSheet1のデータをインポートするテーブルです。
qry1により、table1とtbl1の同じ会員番号のデータを結合します。
その結果をsample2.xlsのqry1というシートに出力するという仕様です。 正常に作動すれば、sample2.xlsのqry1というシートには、
A B C D E 1 会員番号 氏名 出身 血液型 備考 2 1 奥田 美香 東京都 A型 週間文春タバコフォーカス事件にて脱退 3 2 榎田 道子 東京都 AB型 週間文春タバコフォーカス事件にて脱退 4 3 吉野 佳代子 埼玉県 O型 週間文春タバコフォーカス事件にて脱退 5 4 新田 恵利 埼玉県 O型 初期メンバーの中で最も活躍。在籍中にボンド/キャニオンからソロデビュー 6 5 中島 美春 東京都 A型 「なかじ」の愛称で親しまれる 7 6 樹原亜紀 神奈川県 AB型 ニャンギラスの一員として活躍。妙に背が高い 8 7 友田 麻美子 東京都 A型 週間文春タバコフォーカス事件にて脱退
という結果が得られるはずです。
次投稿にて、サンプルデータを作成するコードを提示します。
(ichinose) 2014/09/06(土) 20:35
新規ブックの標準モジュール(Module1)に以下のDB作成プログラムパック
'============================================================================== Private cat As Object 'ADOX.Catalog Function create_cat(flnm As String) As Long On Error Resume Next Set cat = CreateObject("ADOX.Catalog") cat.Create "Provider=Microsoft.jet.OLEDB.4.0;" & _ "Data Source=" & flnm create_cat = Err.Number On Error GoTo 0 End Function '================================================================= Function get_cn() As Object Set get_cn = cat.ActiveConnection End Function '================================================================= Function cr_cmd(text As String, nm As String) As Long On Error Resume Next cr_cmd = 0 cat.Views.Delete nm Err.Clear Dim cmd As Object Set cmd = CreateObject("adodb.command") cmd.CommandText = text cat.Views.Append nm, cmd cr_cmd = Err.Number On Error GoTo 0 End Function '=================================================================== Sub close_cat() On Error Resume Next cat.ActiveConnection.Close Set cat = Nothing On Error GoTo 0 End Sub
標準モジュール(Module2)に
'===================================================================== Option Explicit Sub mk_smp_data() mk_xls mk_mdb End Sub '========================================================================== Sub mk_xls() On Error Resume Next Kill ThisWorkbook.Path & "\sample1.xls" On Error GoTo 0 With Workbooks.Add .Worksheets(1).Name = "Sheet1" With .Worksheets(1) .Range("a1:d1").Value = Array("会員番号", "氏名", "出身", "血液型") .Range("a2:d8").Value = Evaluate("{1,""奥田美香"",""東京都"",""A型"";2,""榎田道子"",""東京都"",""AB型"";" & _ "3,""吉野佳代子"",""埼玉県"",""O型"";4,""新田恵利"",""埼玉県"",""O型"";" & _ "5,""中島美春"",""東京都"",""A型"";6,""樹原亜紀"",""神奈川県"",""AB型"";" & _ "7,""友田麻美子"",""東京都"",""A型""}") End With
If Val(Application.Version) > 11 Then .SaveAs ThisWorkbook.Path & "\sample1.xls", 56 Else .SaveAs ThisWorkbook.Path & "\sample1.xls" End If .Close End With End Sub '================================================================================== Sub mk_mdb() Dim sql_str As String Dim retcode As Long Dim cn As Object Dim biko As Variant Dim g0 As Long On Error Resume Next Kill ThisWorkbook.Path & "\dbsamp.mdb" On Error GoTo 0 If create_cat(ThisWorkbook.Path & "\dbsamp.mdb") = 0 Then Set cn = get_cn sql_str = _ "CREATE TABLE tbl1 (会員番号 integer CONSTRAINT tkey PRIMARY KEY ,備考 varchar(255));" cn.Execute sql_str biko = Array("週間文春タバコフォーカス事件にて脱退", "週間文春タバコフォーカス事件にて脱退", "週間文春タバコフォーカス事件にて脱退", _ "初期メンバーの中で最も活躍。在籍中にボンド/キャニオンからソロデビュー", "「なかじ」の愛称で親しまれる", "ニャンギラスの一員として活躍。妙に背が高い", _ "週間文春タバコフォーカス事件にて脱退") For g0 = LBound(biko) To UBound(biko) sql_str = " INSERT INTO tbl1 " _ & "(会員番号,備考) VALUES " _ & "(" & (g0 + 1) & ",'" & biko(g0) & "');" cn.Execute sql_str Next cr_cmd "SELECT Table1.会員番号, 氏名, 出身, 血液型, 備考 FROM table1 LEFT JOIN tbl1 ON table1.会員番号 = tbl1.会員番号;", "qry1" close_cat End If End Sub
一度、適当なフォルダに保存(VBAsamp.xls)してから、mk_smp_dataを実行してみてください。
上記ブックを保存したフォルダにsample1.xlsとdbsamp.mdbが作成されるはずです。
作成されていたなら、前投稿のようなデータが作成されているか 確認してください。
確認が出来たなら、dbsamp.mdbの標準モジュールにアクセスを使って以下のコードを 作成してください。
Option Compare Database Option Explicit Function Fnインポート() On Error Resume Next Dim Active_mdb As String Dim varac As Variant Dim varxls As Variant Active_mdb = CurrentProject.Path varac = "table1" varxls = Active_mdb & "\sample1.xls" DoCmd.DeleteObject acTable, varac Err.Clear DoCmd.TransferSpreadsheet acImport, 8, varac, varxls, True, "Sheet1!" If Err.Number <> 0 Then MsgBox Err.Description & " : " & Err.Number End If On Error GoTo 0 End Function Function Fnエクスポート() On Error Resume Next Dim Active_mdb As String Dim varac As Variant Dim varxls As Variant Active_mdb = CurrentProject.Path varxls = Active_mdb & "\sample2.xls" DoCmd.TransferSpreadsheet acExport, 8, _ "qry1", varxls, True If Err.Number <> 0 Then MsgBox Err.Description & " : " & Err.Number End If End Function
これは、あやさんが投稿されたものと殆ど同じコードをサンプル仕様用に変えたものです。
尚、アクセスがない場合は、上記のコードは、入れられません。
アクセスアプリを使った場合との対比はできませんが、ExcelVBAで仕様の実行は可能です。
では、次投稿にて、サンプル仕様を実行するコードです。
(ichinose) 2014/09/06(土) 21:03 訂正
では、実際の実行コードです。先にサンプルデータ作成プロフラムを入れたVBAsamp.xlsの 標準モジュール(Module3)にADO関連I/Oパック
'========================================================================== Option Explicit Private cn As Object '========================================================================== Function open_db(dbpath As String, Optional prv As Long = 0) As Long On Error GoTo err_open_db open_db = 0 Set cn = CreateObject("ADODB.Connection") If prv = 0 Then cn.ConnectionString = "provider=Microsoft.jet.OLEDB.4.0;" & "Data Source=" & dbpath Else cn.ConnectionString = "Provider=Microsoft.Ace.OLEDB.12.0;" & "Data Source=" & dbpath End If cn.Open On Error GoTo 0 Exit Function err_open_db: MsgBox Error(Err.Number) & Err.Number open_db = Err.Number End Function '========================================================================== Sub close_db() On Error Resume Next cn.Close Set cn = Nothing On Error GoTo 0 End Sub '========================================================================== Function execute_sql(sql As String, Optional grs As Object = Nothing, Optional er As Boolean = False) As Long On Error GoTo err_sql close_rs grs execute_sql = 0 If grs Is Nothing Then cn.Execute sql Else grs.Open sql, cn, 2, 2 End If On Error GoTo 0 Exit Function err_sql: If er Then MsgBox Err.Description & " : " & Err.Number execute_sql = Err.Number End Function '========================================================================== Sub close_rs(grs As Object) On Error Resume Next grs.Close End Sub
別の標準モジュール(Module4)に
'========================================================================== Option Explicit Sub test1() Dim straccesspath As String Dim objaccess As Object 'エクセル モジュールに記述 'Accessにインポート&★チェック.xlsにエクスポート straccesspath = ThisWorkbook.Path & "\dbsamp.mdb" Set objaccess = CreateObject("Access.Application") objaccess.Opencurrentdatabase straccesspath objaccess.Run "Fnインポート" objaccess.Run "Fnエクスポート" objaccess.closecurrentdatabase objaccess.Quit Set objaccess = Nothing End Sub '========================================================================== Sub test2() Dim rs As Object Dim sql As String On Error Resume Next Kill ThisWorkbook.Path & "\sample2.xls" On Error GoTo 0 If open_db(ThisWorkbook.Path & "\dbsamp.mdb") = 0 Then sql = "drop Table table1;" execute_sql sql sql = "select * into table1 from [Excel 8.0; HDR=Yes;Database=" & ThisWorkbook.Path & "\sample1.xls" & "].[Sheet1$]" execute_sql sql Set rs = CreateObject("adodb.recordset") execute_sql "select * into [Excel 8.0; HDR=Yes;Database=" & ThisWorkbook.Path & "\sample2.xls" & "].[qry1] from qry1;", , True Call close_db End If End Sub
以上です。test1,test2を実行してみてください。どちらでも同じ結果(sample2.xls)が得られることを 確認してください。
test2は、本当なら、一度、mdbにsample1.xlsをインポートしなくても(Table1を作らない) 可能でしたが、今回は、test1と同じような方法で行いました。
尚、dbsamp.mdbに前投稿でのVBAコードを記述しなければ、test1は、エラーになります。 test2は、dbsamp.mdbにvbaコードがなくても作動します。
以上です。Excel2002、2010で確認しました。
うまくいくようなら、ADOの研究をしてみてください。
ただ、アクセスがないと メンテナンスは大変ですよ!!
(ichinose) 2014/09/06(土) 22:02
???さん ichinoseさん ありがとうございます 理解・検証にお時間くださいm(_ _)m
(あや) 2014/09/08(月) 10:13
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.