Очистка сети для данных с динамическим URL-адресом, зависящим от операторов if / elseif - PullRequest
1 голос
/ 14 июня 2019

План состоит в том, чтобы иметь именованный диапазон списка тикеров и бирж, а затем открывать динамический URL и очищать данные из Yahoo Finance.Проблема заключается в том, что я собираю данные с разных бирж, поэтому мне нужен оператор if, elseif, чтобы разделить URL по-разному в зависимости от обмена.

В конце оператора if и оператора With и End With я получаюошибка «[Expression.Error] имя« Источник »не распознано ....».

Я упростил только соответствующий код и жестко закодировал символ как TGIF и обменялся на CN, чтобы его было легче понять.

Я искал на каждом сайте, но ничего не могу найти в этом конкретном сообщении об ошибке,Попробовал гугл и без попаданий, так что эта конкретная ошибка не выглядит так, как если бы она была устранена ранее.

Sub OpenWebStockDataTest()
'
' OpenWebStockDataTest Macro
'

'
    Dim ticker As String
    Dim exchange As String

    ticker = "TGIF"
    exchange = "XCNQ"

    If exchange = "XCNQ" Then
        ActiveWorkbook.Queries.Add Name:="Table 2", Formula:= _
        "let" & Chr(13) & "" & Chr(10) & "    Source = Web.Page(Web.Contents(""https://finance.yahoo.com/quote/" & ticker & ".CN" & "/history?p=" & ticker & ".CN""""))," & Chr(13) & "" & Chr(10) & "    Data2 = Source{2}[Data]," & Chr(13) & "" & Chr(10) & "    #""Changed Type"" = Table.TransformColumnTypes(Data2,{{""Date"", type date}, {""Open"", type number}, {""High"", type number}, {""Low"", type number}, {""Close*"", type number}, {""Adj Close**"", type number}, {""Volume"", Int64" & _
        ".Type}})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & "    #""Changed Type"""

    ElseIf exchange = "XTSX" Then
        ActiveWorkbook.Queries.Add Name:="Table 2", Formula:= _
        "let" & Chr(13) & "" & Chr(10) & "    Source = Web.Page(Web.Contents(""https://finance.yahoo.com/quote/" & ticker & ".V" & "/history?p=" & ticker & ".V""""))," & Chr(13) & "" & Chr(10) & "    Data2 = Source{2}[Data]," & Chr(13) & "" & Chr(10) & "    #""Changed Type"" = Table.TransformColumnTypes(Data2,{{""Date"", type date}, {""Open"", type number}, {""High"", type number}, {""Low"", type number}, {""Close*"", type number}, {""Adj Close**"", type number}, {""Volume"", Int64" & _
        ".Type}})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & "    #""Changed Type"""

    ElseIf exchange = "XTSE" Then
        ActiveWorkbook.Queries.Add Name:="Table 2", Formula:= _
        "let" & Chr(13) & "" & Chr(10) & "    Source = Web.Page(Web.Contents(""https://finance.yahoo.com/quote/" & ticker & ".TO" & "/history?p=" & ticker & ".TO""""))," & Chr(13) & "" & Chr(10) & "    Data2 = Source{2}[Data]," & Chr(13) & "" & Chr(10) & "    #""Changed Type"" = Table.TransformColumnTypes(Data2,{{""Date"", type date}, {""Open"", type number}, {""High"", type number}, {""Low"", type number}, {""Close*"", type number}, {""Adj Close**"", type number}, {""Volume"", Int64" & _
        ".Type}})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & "    #""Changed Type"""

    ElseIf exchange = "XNYS" Or exchange = "XNAS" Or exchange = "OTCM" Then
        ActiveWorkbook.Queries.Add Name:="Table 2", Formula:= _
        "let" & Chr(13) & "" & Chr(10) & "    Source = Web.Page(Web.Contents(""https://finance.yahoo.com/quote/" & ticker & "/history?p="" & ticker""))," & Chr(13) & "" & Chr(10) & "    Data2 = Source{2}[Data]," & Chr(13) & "" & Chr(10) & "    #""Changed Type"" = Table.TransformColumnTypes(Data2,{{""Date"", type date}, {""Open"", type number}, {""High"", type number}, {""Low"", type number}, {""Close*"", type number}, {""Adj Close**"", type number}, {""Volume"", Int64" & _
        ".Type}})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & "    #""Changed Type"""
    End If
    ActiveWorkbook.Worksheets.Add
    With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
        "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=""Table 2"";Extended Properties=""""" _
        , Destination:=Range("$A$1")).QueryTable
        .CommandType = xlCmdSql
        .CommandText = Array("SELECT * FROM [Table 2]")
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = True
        .ListObject.DisplayName = "Table_2"
        .Refresh BackgroundQuery:=False
    End With
    ActiveSheet.Name = "stockData"
End Sub

Он должен открыть соединение с https://finance.yahoo.com/quote/TGIF.CN/history?p=TGIF.CN, но вместо этого я получаю сообщение об ошибке.

1 Ответ

0 голосов
/ 15 июня 2019

Сообщение Expression.Error обычно указывает, что ваш код M / Power Query содержит это неопределенное / неназначенное выражение.(Один из примеров может быть в четвертой ветви вашего оператора IF, где ваша переменная VBA ticker находится внутри самого кода Powery Query. Но сообщение об ошибке предполагает, что выражение Source является проблемой.)


Я бы предложил изменить ваш подход.Если ticker и exchange находятся в некоторых именованных диапазонах в вашей книге Excel, то может быть проще:

  • С помощью Power Query выберите значения ticker и exchange.напрямую (вместо использования VBA)
  • Наличие некоторых условных IF операторов / логики в вашем коде Power Query (вместо VBA) для определения того, каким должен быть URL.
  • Запрос URLиспользуя Power Query (вы уже делаете это, поэтому здесь никаких изменений).

Теоретически, приведенный выше подход устраняет необходимость в VBA, но требует либо:

  • ticker и exchange должны находиться в именованных диапазонах, если ваша таблица запросов находится в той же книге Excel
  • или ticker и exchange не должны находиться в именованных диапазонах, если ваша таблица запросовв другой книге.

В качестве примера, это функция, которая, учитывая имя диапазона, позволит вам получить содержимое этого конкретного именованного диапазона из текущей книги, используяPower Query:

GetNamedRangeInCurrentWorkbook = (nameOfRange as text) as text => Excel.CurrentWorkbook(){[Name=nameOfRange]}[Content][Column1]{0}

И эта функция, которая, если вы дадите ей конкретный обмен и тикер, попытается дать вам URL (при условии, что указанный вами обмен присутствует в наборе exchangeMap expression / recordset).

GetUrlToQuery = (exchangeToQuery as text, tickerValue as text) as text =>
    let
        exchangeMap = [
            XCNQ = ".CN",
            XTSX = ".V",
            XTSE = ".TO"
            // You can continue this for any others that need doing.
        ],
        mappedValue = Record.Field(exchangeMap, exchangeToQuery),
        concatenatedValue = tickerValue & mappedValue,
        url = "https://finance.yahoo.com/quote/" & concatenatedValue & "/history?" & Uri.BuildQueryString([p = concatenatedValue])
    in url,

Собрав их вместе (и предполагая, что у вас есть exchange и ticker в именованных диапазонах), вы можете попробовать что-то вроде:

let
    GetNamedRangeInCurrentWorkbook = (nameOfRange as text) as text => Excel.CurrentWorkbook(){[Name=nameOfRange]}[Content][Column1]{0},
    ticker = GetNamedRangeInCurrentWorkbook("ticker"),
    exchange = GetNamedRangeInCurrentWorkbook("exchange"),
    GetUrlToQuery = (exchangeToQuery as text, tickerValue as text) as text =>
        let
            exchangeMap = [
                XCNQ = ".CN",
                XTSX = ".V",
                XTSE = ".TO"
                // You can continue this for any others that need doing.
            ],
            mappedValue = Record.Field(exchangeMap, exchangeToQuery),
            concatenatedValue = tickerValue & mappedValue,
            url = "https://finance.yahoo.com/quote/" & concatenatedValue & "/history?" & Uri.BuildQueryString([p = concatenatedValue])
        in url,
    url = GetUrlToQuery(exchange, ticker),
    response = Web.Page(Web.Contents(url)),
    data = response{2}[Data],
    changedTypes = Table.TransformColumnTypes(data, {{"Date", type date}, {"Open", type number}, {"High", type number}, {"Low", type number}, {"Close*", type number}, {"Adj Close**", type number}, {"Volume", type number}})
in
    changedTypes

Затем, теоретически,если значения ticker и exchange изменяются, вы можете просто обновить запрос и получить новые данные (при условии, что новые значения ticker и exchange действительны и поддерживаются функцией GetUrlToQuery).

Пример изображения (желтые ячейки - именованные диапазоны, внизу загружена таблица запросов):

Output table

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...