web-dev-qa-db-ja.com

VBAで電源クエリを自動化する方法は?

シート1にデータがあります。通常、クエリを実行して変換を行い、閉じて既存のシート2に読み込みます。

VBAを使用してこれを自動化したいと思います。VBAでは、電源クエリを自動的に実行し、シート2に変換を設定できます。

マクロレコーダーでは、ステップを記録できません。そして、これを行うことについてあまりオンラインではありません。

より簡単なコードを試す:

Sub LoadToWorksheetOnly()

'Sub LoadToWorksheetOnly(query As WorkbookQuery, currentSheet As Worksheet)
    ' The usual VBA code to create ListObject with a Query Table
    ' The interface is not new, but looks how simple is the conneciton string of Power Query:
    ' "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & query.Name

    query = Sheets("Sheet6").Range("A1").value 'here is where my query from power query is. I put the text from power query avanced editor in another sheet cell.
    currentSheet = ActiveSheet.Name
    With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
        "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & query.Name _
        , Destination:=Sheets("target").Range("$A$1")).QueryTable
        .CommandType = xlCmdDefault
        .CommandText = Array("SELECT * FROM [" & query.Name & "]")
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = False
        .Refresh BackgroundQuery:=False
    End With

End Sub

これは、新しいシートに手動でロードしようとするときの問題です。

enter image description here

13
JonnyBoy

仕掛品:

それで十分にこれを書く方法は?一番下の行は、VBAではなく、組み込みツールを使用してクエリを設定する必要があるということです。ファイル、フォルダー、Web、データベース内のファイルのループなど、適切な方法でデータをロードします。リストが続きます。外部ソースからインポートすることも、内部ソースからロードすることもできます。外部ソースからの読み込みの詳細については、 こちら をご覧ください。

ソースを保護してロードすると、クエリエディタが表示され、変換を実行できます steps

ポイントは、UIを使用して手順を実行すると、Mコードがバックグラウンドで記述され、ソース形式や場所を変更しない限り、再利用可能なクエリの基礎を形成するということです。

あなたの場合、ステップを実行し、希望するクエリがある場合は、シート2を閉じてロードします。

このステップでは、最初にこれを設定するときに、シート2を閉じて読み込み先として選択します。

Close and load

注意:既存のシートを選択するときは、シート2がすでに存在していることを確認してください。Sheet2を手動で編集できます。推奨範囲の前。


このすべてをコードで再作成しようとするため、問題が発生しています。

しないでください。 UIを使用してセットアップし、sheet2にロードします。その後、クエリエディタを開いて手順を編集するか、クエリを更新して、既存のsheet2に新しい/更新されたデータをロードします。


クエリを更新するために利用できるいくつかの方法:

クエリは、VBA /手動更新によって、それが存在するシート(シート2)またはワークブック自体(例: Sheet2.CalculateThisWorkbook.RefreshAll、[データ]タブの[ブックの更新]ボタンを手動で押す(これらはすべてやりすぎです)

Refresh all tab

よりターゲットを絞った方法:

シート2のクエリテーブルのVBA:

ThisWorkbook.Worksheets("Sheet2").ListObjects(1).QueryTable.Refresh BackgroundQuery:=False   

上記を適切な表などに変更します。

クエリテーブル自体を右クリックして、更新を選択します。

Refresh

問題のクエリの右側にあるワークブッククエリウィンドウの更新ボタンをクリックします(緑色の丸い矢印のアイコン)

Refresh


ケンプル VBAの方法(私からの小さな編集)

Option Explicit
Public Sub UpdatePowerQueries()
    ' Macro to update my Power Query script(s)

    Dim lTest As Long, cn As WorkbookConnection
    On Error Resume Next
    For Each cn In ThisWorkbook.Connections
        lTest = InStr(1, cn.OLEDBConnection.Connection, "Provider=Microsoft.Mashup.OleDb.1", vbTextCompare)
        If Err.Number <> 0 Then
            Err.Clear
            Exit For
        End If
        If lTest > 0 Then cn.Refresh
    Next cn
    On Error GoTo 0
End Sub

VBAを介してこのすべての作業を行う必要はありません。 VBAでより快適に実行でき、処理されたデータをソースとしてPowerQueryにアクセスさせることで、より巧妙なデータ操作ができる場合があります。処理ルーチンを呼び出し、上記のVBAコマンドメソッドのいずれかを使用するサブルーチンを使用することで、ロット全体を起動できます。他にもメソッドがあり、時間があれば追加します。


計算:

PowerQuery出力に依存する計算がある場合、4つの明白な即時オプションがあります。

  1. 可能であれば、これらの計算をPowerQueryに追加します。計算列、ユーザー定義関数などをサポートしています。
  2. PowerQuery出力をデータモデルに追加し、データモデルを使用して計算フィールドを含む計算を実行します。これにより、タイムインテリジェンス機能にもアクセスできます。
  3. 更新時に範囲が変更された場合、VBAを使用して、シート2の適切な領域に計算を追加します
  4. 更新時に範囲が変わらない場合は、数式を邪魔にならないようにしてください。
11
QHarr

上記の答えの前提に同意しません。 VBAは、PowerQueryの自動化に最適であり、繰り返し作業に特に効率的です。秘Theは、最初にPowerQueryで必要なクエリを作成してから、アドバンストエディターを使用してMをキャプチャすることです。コピーしてワークブックのセルまたは別のテキストファイルに保存します。

method は、Gil Ravivによって詳細に説明されています。便宜上、ワークブックではなくテキストファイルにMを保存し、次のようにロードします。

Function LoadTextFile(FullFileName As String) As String
  With CreateObject("Scripting.FileSystemObject")
    LoadTextFile = .OpenTextFile(FullFileName, 1).readall
  End With 
End Function

テキストファイルの良いところは、Excelから独立しており、多くのブックで再利用できることです。

ここにいくつかのMがあります:

let
// load the reference file (variables are shown in capitals;  
// variable values are replaced with strings from the Excel control workbook)
    Source = Excel.Workbook(File.Contents(PATH_AND_NAME), null, true),
    ImportSheet = Source{[Item=SHEET_NAME,Kind="Sheet"]}[Data],
    #"Promoted Headers" = Table.PromoteHeaders(ImportSheet),
    #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"ACCOUNT", type text}})
in
    #"Changed Type"

(ワークブックまたはテキストファイルから)VBAに読み込まれた後、MはVBA内で編集できます。たとえば、プレースホルダーワードを置き換えるか、必要に応じてMコマンド名を使用して行を見つけて変更します。

    ' create the M script to read the M file that will do the import
        M_Script = LoadTextFile(M_Source)

    ' insert the path
        M_Script = Replace(M_Script, "PATH_AND_NAME", """" & qSource & """") 

    ' insert the worksheet name
        If wksName <> "" Then M_Script = Replace(M_Script, "SHEET_NAME", """" & wksName & """")

次のステップは、クエリをロードすることです。 Gilによって記述された技術 を使用してこれを行います:

Dim qry As WorkbookQuery

If DoesQueryExist(qName) Then 
    ' Deleting the query 
    Set qry = ThisWorkbook.Queries(qName) 
    qry.Delete 
End If 

Set qry = w.queries.Add(qName, M_Script, qSource)

' We check if data should be loaded to Data Model 
shouldLoadToDataModel = ThisWorkbook.Worksheets(1).Cells(13, "D") 

' We check if data should be loaded to worksheet 
shouldLoadToWorksheet = ThisWorkbook.Worksheets(1).Cells(13, "E") 

If shouldLoadToWorksheet Then 
    ' We add a new worksheet with the same name as the Power Query query 
    Set currentSheet = Sheets.Add(After:=ActiveSheet) 
    currentSheet.Name = qName 

    If Not shouldLoadToDataModel Then 
        ' Let's load to worksheet only 
        LoadToWorksheetOnly qry, currentSheet 
    Else 
        ' Let's load to worksheet and Data Model 
        LoadToWorksheetAndModel qry, currentSheet 
    End If 
ElseIf shouldLoadToDataModel Then 
    ' No need to load to worksheet, only Data Model 
    LoadToDataModel qry 
End If 

Gilのコードでは、データモデルまたはワークシートにデータをインポートできます。 OPには2番目のメソッドが必要です。メソッドが実行されると、変換されたデータがワークシートに表示されます。

7
mer_curius