[[20201006172606]] 『クエリのVBAについて』(りぃ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『クエリのVBAについて』(りぃ)

お知恵を拝借させていただければ幸いです。

GetOpenFileでcsvを選択し、そのcsvをクエリに取り込み色々加工してから吐き出すVBAを作成しています。
やりたいこととして、このマクロを実行するシート名に合わせてクエリの名前を変えたいです。

ActiveSheetの名前を変数"a"に取得し、その変数をクエリの名前の部分と置換してみたところ、
「クエリ"a"が見つかりませんでした」というエラーが出てしまいます。

 ※変数aを固定の名称の場合は正常に動くことを確認済みです

以下が置換した後のソースとなります。

    Dim a As String

    a = wks.name

    Set qry = wkb.Queries.Item(a)
    qry.Delete

    'クエリの生成
    Set qry = wkb.Queries.Add(a, form)

    'シートへの書き出し
    With wks.ListObjects.Add(SourceType:=0, Source:= _
        "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=a;Extended Properties=""""" _
        , Destination:=Range("$A$1")).QueryTable
        .CommandType = xlCmdSql
        .CommandText = Array("SELECT * FROM [a]")
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = True
        .ListObject.DisplayName = a
        .refresh BackgroundQuery:=False
    End With

この時、クエリの生成は出来ているため
シートでの書き出しのどこかで詰まっているのだとは思いますがどこが原因かわかりません。

何が原因か教えていただけますと幸いです。
よろしくお願いいたします。

< 使用 Excel:Excel2016、使用 OS:Windows10 >


 全体を見ていないですが、

    Set qry = Nothing
    On Error Resume Next
    Set qry = wkb.Queries.Item(a)
    On Error Goto 0

    If Not qry Is Nothing Then qry.Delete

 としても変わらないでしょうか。
(QS) 2020/10/06(火) 18:52

 こんばんは!
試しに↓これをコメントにして
.ListObject.DisplayName = a

 そのシートモジュールに↓としてみてはどうでしょうか?
Option Explicit
Sub mm()
Dim Qu As Object
For Each Qu In Me.ListObjects
  Debug.Print Qu.Name
Next
End Sub
(SoulMan) 2020/10/06(火) 20:37

QSさん

クエリが存在しない状態のケアは確かにしていませんでしたので助かりました。
ありがとうございます。

ただ、元々クエリの生成まではできているためご提示の部分はクリアできています。
With〜End Withのどこかで詰まっているものと思っております。

SoulManさん

ListObectsに対して、メソッドまたはデータメンバが見つかりません。
のエラーがでます。

Meキーワードというものを初めて知ったため
後学のためにどのような処理をしようとしていたのか教えていただけると幸いです。

(りぃ) 2020/10/07(水) 13:03


 こんばんは!
あっ、そうなんですね。。。
ということはそのシートのテーブルがないんですね????
私も最近全くやってないので自分のPCを検索したら↓こんなコードが出てきました。。。
動くかどうかわかりませんが、、、SqlとPathを変更して何かの参考になりませんでしょうか????

 Option Explicit
Public MyFlag As Boolean
Dim MyClassQueryTable As New Class1
Sub RunQTEvent()
    MyClassQueryTable.MyQueryEvent QT:=ActiveSheet.QueryTables(1)
End Sub
Sub Macro1()
Dim MyQtName As String
Dim MyQt As QueryTable
Dim MyName As String
Dim MyBook As String
Dim MyDest As Range
Dim nn As Name
Dim x As Long
For Each MyQt In ActiveSheet.QueryTables
    MyQt.Delete
Next
For Each nn In ThisWorkbook.Names
    nn.Delete
Next
ActiveSheet.Cells.ClearContents
MyBook = ThisWorkbook.Path
MyBook = MyBook & "\" & "Data.xls"
Set MyDest = ActiveSheet.Range("A1")
MyFlag = False
On Error Resume Next
ActiveSheet.QueryTables.Item(1).Refresh
On Error GoTo 0
If MyFlag = False Then
    With ActiveSheet.QueryTables.Add("ODBC;DSN=Excel Files;DBQ=" & MyBook, MyDest)
        .Sql = "SELECT * FROM `T_住所$` WHERE (名前 Not Like '%高嶋%')"
        .Name = "MyQuery"
        .Refresh
    End With
    MsgBox ActiveSheet.QueryTables.Item(1).Name
    RunQTEvent
End If
End Sub

 クラスモジュールに↓
Option Explicit
Public WithEvents MyQueryTable As QueryTable
Sub MyQueryEvent(QT As Object)
    Set MyQueryTable = QT
End Sub
Private Sub MyQueryTable_BeforeRefresh(Cancel As Boolean)
    MyFlag = True
End Sub
(SoulMan) 2020/10/07(水) 19:28

 >Meキーワードというものを初めて知ったため
シートモジュールにMeと書くとそれはその言葉のごとくシートです。

 Meと打って . ドットを打つとそのメンバーが表示されます。

 ThisWorkBookモジュールにMeと打つとそれは、Bookです。
要は、オブジェクトでMeとは自分自身のことです。。。

 多分、、お分かりの上で質問されてるのでしょうけど。。。
まぁ、、ごくごく普通のことですよね?????

 >※変数aを固定の名称の場合は正常に動くことを確認済みです
なのでテーブルはあるとして、、名前はExcelが勝手につけますから。。。
どんな名前になっているか調べてみてはどうでしょうか?
と思った次第です。。。
でも、、見当違いだったみたいですね。。。失礼しました。。。

 ちなみに上のコードは2005年に書いたものでした。。。
(SoulMan) 2020/10/07(水) 19:38

SoulManさん

 >シートモジュールにMeと書くとそれはその言葉のごとくシートです。
なるほど…検索をかけたのですがいまいち飲み込めていなかったのでありがたいです。
ちなみに本当に理解していませんでした…申し訳ありません。

 >ということはそのシートのテーブルがないんですね????
正確に言うとテーブルの生成までは出来ているようです。
シート状に「Sheet1」という名前のテーブルは出来ていて、そこの見出し行に
"ExternalData_1 : データの取り出し中..."
と書かれている状態になります。

 この時、クエリの名前も当然「sheet1」なのですが、VBAでのエラーが
「クエリ"a"が見つかりませんでした」ということを考えると
"a"が変数でなく名前として受け渡されてしまっている気もしてきました。

 >私も最近全くやってないので自分のPCを検索したら↓こんなコードが出てきました。。。
ありがとうございます。
VBAの知識がまばらにしかないのでゆっくりですが読み解きたいと思います。
(りぃ) 2020/10/08(木) 11:08

>ということはそのシートのテーブルがないんですね????
追伸です、前回行った時はマクロ実行前の状態で行っていたので見つからなかっただけでした…
実行後に動かしたらきちんと「Sheet1」が表示されていました。すみません。
(りぃ) 2020/10/08(木) 11:32

 こんばんは!

 >"a"が変数でなく名前として受け渡されてしまっている気もしてきました。
 それは、ブレイクポイントを設定するとかDebug.Printで書き出すとかすればいいでしょう。

 注意しなければいけないことはその名前が既に使われている可能性があるということです。
15年前に書いた私のコードでも一度全ての名前を削除しています。

 つまり↓この部分は使われていない名前ならば登録できると思います。
 >.ListObject.DisplayName = a
 なので何が目的なのかわかりませんが、、名前はExcelに任せてコメントにしてもコードは走ると思います。
 後で名前を取得すればいいでしょう。

 どうしても名前をコントロールしたいときはその名前がないことを確認してから代入してみてはどうでしょうか?
(SoulMan) 2020/10/08(木) 20:45

 横から失礼します。

  .CommandText = Array("SELECT * FROM [a]")
 ここのaがおかしくないですか?
 変数ではなく文字列になっています。

 もし関係なければスルーしてください。
(めいぷる) 2020/10/09(金) 11:54

 めいぷる さん ありがとうございます。
ほんとですね。。
多分、そうですね。。。
(SoulMan) 2020/10/09(金) 13:27

 めいぷるさん
恐らくそこですね。ありがとうございます。
私の理解不足の結果の見落としです。
テーブル名を受け渡せるように修正したいと思います。

 soulManさん
色々とご協力・考察してくださりありがとうございました。
一応シート内とクエリは全てクリアするようにしておりましたが、
今後作業で詰まった場合はその観点にも着目したいと思います。

 今回質問させていただき、今までやりたい作業をするためだけにVBAを触っていたツケを感じました。
基本を勉強していなく、ご迷惑をおかけしました。精進していきます。
(りぃ) 2020/10/09(金) 14:18

 お世話になっております。
 皆様のおかげで無事に希望の動作を行うことができました。
 大変感謝しております。
 もし同様の処理を行いたい方がいたら何かの参考になればと思い、最終ソースを貼らせていただきます。
 (ソースの記述にお見苦しい点があるとは思いますがご容赦ください)


 Option Explicit

 '変数宣言
 Dim form    As String
 Dim qry     As WorkbookQuery
 Dim wkb     As Workbook
 Dim wks     As Worksheet

 Sub 取り込み()
     Dim Pa    As String
     Dim sheetname As String

     '再計算停止
     Application.Calculation = xlCalculationManual
     '描画停止
     Application.ScreenUpdating = False

     Set wkb = ActiveWorkbook
     Set wks = ActiveSheet

     ChDir ThisWorkbook.Path

     'ファイル選択
     Pa = Application.GetOpenFilename(",*.csv")

     If Pa <> "False" Then

         '加工条件を指定
         form = "let" & _
                "    ソース = Csv.Document(File.Contents(""" & Pa & """),[Delimiter="","", Columns=6, Encoding=932, QuoteStyle=QuoteStyle.None])," & _
                "    フィルターされた行 = Table.SelectRows(ソース, each ([Column6] <> """"))," & _
                "    昇格されたヘッダー数 = Table.PromoteHeaders(フィルターされた行, [PromoteAllScalars=true])," & _
                "    フィルターされた行1 = Table.SelectRows(昇格されたヘッダー数, each ([#""比較結果(簡易)""] <> ""スキップされたファイル""))," & _
                "    追加された条件列 = Table.AddColumn(フィルターされた行1, ""カスタム"", each if [拡張子] = ""h"" then ""ヘッダー"" else if [拡張子] = ""nfc"" then ""ファイル名(コメント・定義部)"" else if [拡張子] = ""s"" then ""アセンブラ"" else ""関数"")," & _
                "    削除された列 = Table.RemoveColumns(追加された条件列,{""左更新日時"", ""右更新日時"", ""拡張子""})," & _
                "    並べ替えられた列 = Table.ReorderColumns(削除された列,{""フォルダー"", ""名前"", ""カスタム"", ""比較結果(簡易)""})," & _
                "    名前が変更された列 = Table.RenameColumns(並べ替えられた列,{{""カスタム"", ""分類""}})," & _
                "    フィルターされた行2 = Table.SelectRows(#""名前が変更された列"", each ([フォルダー] <> """"))," & _
                "    フィルターされた行3 = Table.SelectRows(フィルターされた行2, each not Text.Contains([フォルダー], ""Tool""))" & _
                "in" & "    フィルターされた行3" & ""

         'ワークシートをクリア
         wks.Cells.Clear

         Call csv取り込み(form, wkb, wks)

         MsgBox ("  *取得完了しました*")

     Else
     End If

     '計算再開
     Application.Calculation = xlCalculationAutomatic
     '描画再開
     Application.ScreenUpdating = True

 End Sub

 Sub csv取り込み(form As String, wkb As Workbook, wks As Worksheet)

     Dim wksname As String
     Dim con As WorkbookConnection

     wksname = wks.name

     '同名クエリ削除
     Set qry = Nothing
     On Error Resume Next
     Set qry = wkb.Queries.Item(wksname)
     On Error GoTo 0

     If Not qry Is Nothing Then qry.Delete

     'クエリの生成
     Set qry = wkb.Queries.Add(wksname, form)

     'シートへの書き出し
     With wks.ListObjects.Add(SourceType:=0, _
         Source:="OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & wksname & ";Extended Properties=""""", _
         Destination:=Range("$A$1")).QueryTable
         .AdjustColumnWidth = True
         .BackgroundQuery = True
         .CommandText = "SELECT * FROM" & " [" & wksname & "]"
         .RefreshStyle = xlInsertDeleteCells
         .RefreshPeriod = 0
         .ListObject.DisplayName = wksname
         .refresh BackgroundQuery:=False
     End With

     '接続全削除
     For Each con In wkb.Connections
         con.Delete
     Next

 End Sub

(りぃ) 2020/10/12(月) 17:11


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.