Access VBAよりExcelのシート名を取得

このQ&Aのポイント
  • Access VBAを使用してExcelファイルのシート名を取得する方法について質問しています。特定のエラーメッセージが表示されるため、情報をまとめていただきたいです。
  • Access2010とWindows7 Proを使用してExcelファイルのシート名を取得するVBAコードについて質問しています。具体的なエラーメッセージと参照設定の問題について教えていただきたいです。
  • Excelのシート名を取得するためにAccess VBAを使用していますが、実行時エラー3170「インストール可能なISAMドライバーが見つかりませんでした。」が表示される問題が発生しています。参照設定のチェックができない原因についても教えていただければ幸いです。
回答を見る
  • ベストアンサー

Access VBAよりExcelのシート名を取得

お世話になります。 Access2010 Windows7 Pro 以下のページを参考にしましたが、「実行時エラー3170 インストール可能なISAMドライバーが見つかりませんでした。」と表示されてしまいます。 http://www.accessclub.jp/bbs5/0005/vba1231.html Dim Db As DAO.Database Dim Tbl As DAO.TableDef Dim xlsFile As String xlsFile = "ファイルパス" Set Db = OpenDatabase(xlsFile, True, True, "Excel 14.0;") ←ここで止まる For Each Tbl In Db.TableDefs If Right$(Tbl.Name, 1) = "$" Or _ Right$(Tbl.Name, 2) = "$'" Then 'シート名の最後は必ず$が付きます Debug.Print Tbl.Name End If Next Tbl Db.Close Set Db = Nothing なお、参照設定にて「Microsoft DAO 3.6 Object Library」にチェックが入っていないことが原因かと思い、チェックを入れようとしましたが「この名前は既にあるモジュール、プロジェクト、オブジェクトライブラリで使われています。」というメッセージが表示され、チェックを入れることができません。 勉強不足で大変恐縮ですが、これらのメッセージからどういうことが分かりますでしょうか。 ご教授の程、宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

Set Db = OpenDatabase(xlsFile, True, True, "Excel 14.0;") ←ここで止まる を Set Db = OpenDatabase(xlsFile, True, True, "Excel 12.0;") '←ここで止まる ならOffice2010では出来ましたよ? アプリケーションのバージョンではなくファイルのバージョン指定っぽいです。 ちょっと蛇足かもしれんが、参考になると思われます。 ・・・本来 Null でない Excel 列内の一部の値が Null として返されることがあります・・・ http://support2.microsoft.com/kb/194124/ja >この名前は既に・・・ Microsoft DAO 3.6 Object Library の上位バージョンの Microsoft Office 14.0 Access Database Engine Object Library に チェックが入っていれば OK です。

naoto0216
質問者

お礼

NotFound404さま いつもご回答ありがとうございます。 仰る通り、12にしてみたらいけました!! Excel2010=Excelバージョン14と思って、14を指定したのですが。。 ちなみにファイルのバージョンとはどこを見れば確認できますでしょうか。 >Microsoft Office 14.0 Access Database Engine Object Library に >チェックが入っていれば OK です。 そうでしたか。そちらのチェックは元々入っておりました。 ご教授ありがとうございます。

その他の回答 (3)

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.4

Access VBAにてExcelファイルのシート名を取得したい http://answers.microsoft.com/ja-jp/office/forum/office_2010-access/access/ae9cdecf-0721-40f2-8a89-caa0f5e5dddb でも質問されているようですが、以下に違う方法を紹介しておきます。 (ADO は使える環境になっているものとして) Public Sub Samp1()   Dim cn As New ADODB.Connection   Dim rs As ADODB.Recordset   Dim sA() As String   Dim i As Long   Const CFILE As String = "Excelファイルのフルパス"   cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" _       & "Data Source=" & CFILE & ";" _       & "Extended Properties='Excel 12.0'"   i = 0   Set rs = cn.OpenSchema(adSchemaTables)   While (Not rs.EOF)     ReDim Preserve sA(i)     sA(i) = Left(rs("TABLE_NAME"), Len(rs("TABLE_NAME")) - 1)     i = i + 1     rs.MoveNext   Wend   rs.Close   Set rs = Nothing   cn.Close ' ' この後、sA の配列( 0 スタートの添え字)にシート名が入っているので、 ' 続けて処理するとか ' End Sub ※ 一応、Excel ファイルが xls でも、変更することなく動くみたい ※ 2000 / 2003 で動かすのなら、以下2か所を変更してください Microsoft.ACE.OLEDB.12.0 ↓ Microsoft.Jet.OLEDB.4.0 Excel 12.0 ↓ Excel 8.0

回答No.3

私にExcelのことをお尋ねになるのは後悔することになるかも? 大別すると、対象とするファイルの拡張子が XLS なら 8.0 で十分ですが(Excel1997以降)、 XLSX(XLSMなども)も含めるのならなら 12.0 (Excel2007以降)です。 つまり、生(なま)のデータの入れ物としてのフォーマットは現時点では上記の二種類です。 それに各バージョンで書式や関数などが付加されている・・・と考えて良いのではと思います。 こんな処でご勘弁ください。

naoto0216
質問者

お礼

NotFound404さま ご回答ありがとうございます。 そもそも「シート名を取得する」ということで、ヒットしたページに記載のあったものをコピペしただけで試した状況です。。なので、Excelのバージョン云々以前に、  Set Db = OpenDatabase(xlsFile, True, True, "Excel 12.0;") が何をしているかも理解できておりません。 恐らくシート名を取得する為に、そのExcelファイルのパスを指定し、かつ、そのバージョンを指定している・・ぐらいしか理解できておりません。 その後の、  For Each Tbl In Db.TableDefs If Right$(Tbl.Name, 1) = "$" Or _ Right$(Tbl.Name, 2) = "$'" Then の部分に関してはさっぱりです。 もう少し勉強した上で質問させて頂こうと思います。 ありがとうございました。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

Excelをデータベースとして開くのではなく、OLEオートメーションで操作します。 Dim APL 'アプリケーション Dim WBS 'ワークブック・コレクション Dim WKB 'ワークブック・オブジェクト Dim WSS 'ワークシート・コレクション Dim WKS 'ワークシート・オブジェクト Dim シート数 Dim 索引 Dim シート名 Dim パス名 Dim パス名 = "~" 'Excelアプリケーションをインスタンス化する Set APL = CreateObject("Excel.Application") ワークブック・コレクションを取得する Set WBS = APL.Workbooks ワークブックを開いて、ワークブック・オブジェクトを取得する Set WKB = WBS.Open(パス名) 'エラーハンドリング要 ワークシート・コレクションを取得する Set WSS = WBK.WorkSheets 'シート数を取得する シート数 = WSS.Count '各シートについて処理する For 索引 = 1 To シート数   'ワークシート・オブジェクトを取得する   Set WKS = WSS(索引)   'シート名を取得する   シート名 = WKS.Name   'シート名による処理   ★略   'ワークシート・オブジェクトを解放する   Set WKS = Nothing Next 'ワークシート・コレクションを解放する Set WSS = Nothing 'ワークブックを閉じる WKB.Close 'ワークブック・オブジェクトを解放する Set WKB = Nothing 'ワークブック・コレクションを解放する Set WBS = Nothing 'アプリケーションを終了する APL.Quit 'アプリケーションを解放する Set APL = Nothing 丁寧にコードを書きましたが、中間オブジェクトを省略することも できます。但し、内部でどのようなことが行われているかを知れば、 中間オブジェクトを省略することが、ものすごく効率が悪いという ことを知るべきでしょう。特に変数が静的な場合は解放を怠ると、 メモリが解放されず、重ねて使うと、メモリストレスが増大します。 尚、オブジェクトのプロパティやメソッドの引数、及び戻り値の 内部形式は全てVariant型です。そうでないものは変換されて 使用されます。このため、サンプルでは変数は全て型指定を省略 してVariant型でやっています。 OLEオートメーションではExcelのVBAと同じことができます。 但し、xl~のようなExcelマクロ固有の定数は使用できません。

naoto0216
質問者

お礼

nda23さま 詳しいご回答ありがとうございます。 説明不足で申し訳ございません。。。実は当該AccessはRuntime環境で利用することを想定し、作り込みを行っております。 よって、「CreateObjectを使えない」状況です。 教えて頂いた方法は今回使えませんが、大変勉強になりました。 ありがとうございました。

関連するQ&A

  • AccessからExcelファイルのシート名

    よろしくお願いします WinXP pro Access2000を使用しています 現在 Dim DB As DAO.Database Dim Tbl As DAO.TableDef Dim nCount As Long Dim ArrSheets As String nCount = 0 ArrSheets = Array() Set DB = OpenDatabase("ファイルパス", True, True, "Excel 8.0;") For Each Tbl In DB.TableDefs If Right$(Tbl.Name, 1) = "$" Or Right$(Tbl.Name, 2) = "$'" Then ReDim Preserve ArrSheets(nCount) ArrSheets(nCount) = Mid(Tbl.Name, 1, InStr(1, Tbl.Name, "$", 1) - 1) nCount = nCount + 1 End If Next Tbl DB.Close Set DB = Nothing という風にしてExcelファイルのシート名を取得しているのですが これだと、保護されているExcelファイルのシート名は取得できません 保護されているExcelファイルのシート名を取得する場合 どのようにしたらいいのでしょうか? よろしくお願いします

  • アクセスVBAです

    Sub test() Dim DB As Database Dim T As TableDef Dim myTable As String myTable = "Table1" Set DB = OpenDatabase(CurrentProject.FullName) For Each T In DB.TableDefs If T.Name = myTable Then DoCmd.DeleteObject acTable, myTable Exit For End If Next DB.Close Set DB = Nothing End Sub これを実行しようとすると Dim DB As Database の部分で コンパイルエラー プロジェクトではなく、ユーザ定義型を指定してください。 と言うエラーになります。 Dim DB As Objectにすればエラーにならずに進みますが 何が原因なのでしょうか?

  • vbaコードが遅い

    当方access2003、XP、メモリ2G、コア2DUOなのですが Sub 取得() Dim DB As DAO.Database Dim T As TableDef Set DB = CurrentDb Debug.Print "開始:" & Now For Each T In DB.TableDefs 'ここでやたら時間がかかる Debug.Print T.Name & "取得時間:" & Now Next End Sub これを実行すると、 For Each T In DB.TableDefs を通る時に5秒くらい時間がかかりますがそういうものなのでしょうか?

  • Access97のVBAについて教えて下さい。

    Access97のVBAで、TableDef オブジェクトを作成したいのですが、 実行時に、「オートメーションエラー」になってしまいます。 Dim MyTable As TableDef (Dim MyTable As TableDefsも駄目でした。) 参照設定等で何か抜けがあるのでしょうか? どなたか、教えて下さい。宜しくお願い致します。

  • AccessVBAのCurrentDbメソッドでエラーになります

    Windows2000、Access2000を使っています。 オンラインヘルプを参考に作った下記のプログラムを走らせると、Set db = CurrentDbのところで「実行時エラー13:型が一致しません」のエラーになります。どうしてでしょう。 Sub b() Dim db As DAO.Database Dim tdf As DAO.TableDef Dim fld As DAO.Field Set db = CurrentDb Set tdf = db.TableDefs("テーブル1") For Each fld In tdf.Fields Debug.Print fld.Name Next fld End Sub 参照設定を見ると、Microsoft dao 3.0 Object LibraryにチェックがついていますのでDAOは使えるはずなんですが・・・。

  • Access 2000 の VB での テーブル作成について質問です。

    下記のようにAccess 2000のVBからDAOを使ってテーブルを作っておりますが、 作るフィールドに規定値の設定もVBからできないのでしょうか?DAOだと無理なのでしょぅか? 教えてください Dim db As DAO.Database Dim tbdef As DAO.TableDef Dim flID As DAO.Field Set db = CurrentDb Set tbdef = db.CreateTableDef("テーブル") Set flID = tbdef.CreateField("ID", dbInteger)   tbdef.Fields.Append flID   db.TableDefs.Append tbdef db.Close: Set db = Nothing

  • Access :ALTER TABLE で作成した文字列フィールドがトリミングされない

    いつもお世話になっております。 Access2000を使用しております。 Accessで作成した、あるシステムのバージョンアップを行っております。 その際、複数のテーブルにフィールドを追加する移行プログラムを作成しております。 Dim DB As DAO.Database Set DB = OpenDatabase("外部DB.MDB") DB.Execute ("ALTER TABLE 既存テーブル ADD 追加フィールド CHAR(255)") DB.Close 'データベースを閉じる Set DB = Nothing 上記のようなプログラムを走らせたのですが、 作成された追加フィールドにデータを入力すると、 入力した値の後に指定サイズ分の空白文字ができてしまいます。 つまり、10文字入力した場合 255-10=245文字が空白として登録されてしまいます。 Unicode圧縮プロパティのせいかな、と思い、 Dim TBL As DAO.TableDef Dim FLD As DAO.Field Dim prUC As DAO.Property Set TBL = DB.TableDefs("既存テーブル") Set FLD = TBL.Fields("追加フィールド") Set prUC = FLD.Properties("UnicodeCompression") prUC.Value = True と、フィールド追加後にプロパティを変更してみたりもしたのですが、 やはり、空白が出てしまいます。 作成したフィールドの空白文字がセットされないようにするにはどのようなことを行えばよいのでしょうか。 ご教授のほど、宜しくお願い致します。

  • アクセス フォームが存在するかを一発で取得したい

    フォームが50個くらいあるのですが 該当のフォームが存在するかvbaで取得したいのですが If CurrentProject.AllForms("フォーム1").IsLoaded Then のように、一発で取得する方法はありますか? 今は Sub Sample1() Dim DB As DAO.Database Dim f As DAO.Document Set DB = CurrentDb Dim strForm As String Dim flg As Boolean strForm = "Fメインメニュー" For Each f In DB.Containers!Forms.Documents If strForm = f.Name Then flg = True Exit For End If Next If flg = False Then MsgBox strForm & "は存在しません" End If End Sub のような感じで、すべてのフォームをループしているのですが 無駄が多い気がします。 改善策があればお願いします。

  • DAO エクセルvbaからアクセスのレコードの件数

    DAOで、エクセルvbaからアクセスのレコードの件数を取得したいのですが Dim ac As Object Dim db As DAO.Database Dim rs As DAO.Recordset Set ac = CreateObject("Access.Application") Set db = ac.DBEngine.OpenDatabase("D:\あああ.accdb", False, True) Set rs = db.OpenRecordset("SELECT * FROM Tマスタ WHERE masterkey like '*四*';") i = rs.RecordCount Debug.Print rs("masterkey") rs.Close: Set rs = Nothing db.Close: Set db = Nothing ac.Quit: Set ac = Nothing をすると、抽出するレコードが1000件でも、必ず1が返ります。 masterkeyフィールドは文字列型です。 なぜ実際はたくさんのレコードがあるのに、1が返るのでしょうか?

  • Access VBA 削除

    またお世話になります。 Access2003を使用しています。 不要になったアカウントを削除できるようなものを作成したいのですがうまくいきません。 リストボックスに表示されたアカウントを選択し、 ボタンを押すとテーブルから削除できるというものを考えています。 テーブル名: tbl_ユーザー フィールド名: ユーザー名 パスワード アカウント フォーム名: frm_Account_Delete  リストボックス: UserList  コマンドボタン: Del いろいろ調べて自分なりに作ってみたのですがエラーが出てしまいました。 ―――以下VBAコード――― Dim db As Database Dim rs As DAO.Recordset Set db = CurrentDb() Set rs = db.OpenRecordset("tbl_ユーザー") If IsNull(UserList) Then MsgBox "削除するアカウントを選択してください" Else If MsgBox(UserList & "を削除しますか?", vbYesNo) = vbYes Then db.TableDefs.delete UserList     MsgBox "UserListを削除しました。" End If End If rs.Close db.Close Set db = Nothing ―――以上――― これだと”このコレクションには項目がありません”というエラーが出ます。 アドバイスをよろしくお願いします。