Последние нули усекаются при получении внешних данных - PullRequest
0 голосов
/ 28 марта 2020

При импорте данных из Интернета в Excel 2019, выбрав Data>Get Data>From Other Sources>From Web, последние (конечные) нули чисел обрезаются, что приводит к следующему столбцу «Импорт»:

EU
Import | Desired
968,8  |  968800
891,01 |  891010
413,47 |  413470
410,3  |  410300
43,25  |   43250
17,8   |   17800
15,05  |   15050
3,61   |    3610
6,05   |    6050
4,9    |    4900

US
Import | Desired
968.8  |  968800
891.01 |  891010
413.47 |  413470
410.3  |  410300
43.25  |   43250
17.8   |   17800
15.05  |   15050
3.61   |    3610
6.05   |    6050
4.9    |    4900

Я хотел бы преобразовать данные, которые являются текстовыми (запятые, точки - это оставшиеся тысячи разделителей), в числа, как в столбце «Желательно».

Я перебил следующую рабочую функцию VBA:

Option Explicit

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function UnTruncate(SourceVariant As Variant, _
  Optional TruncateString As String = "0", _
  Optional SplitSeparator As String = ",", _
  Optional NumberOfDigits As Long = 3) As Long

    Dim vnt As Variant        ' String Array (0-based, 1-dimensional)
    Dim strSource As String   ' Source String
    Dim strResult As String   ' Resulting String
    Dim strUB As String       ' Upper Bound String
    Dim i As Long             ' String Array Elements Counter

    ' Convert SourceVariant to a string (Source String (strSource)).
    strSource = CStr(SourceVariant)

    ' Check if Source String (strSource) is "" (UnTruncate = 0, by default).
    If strSource = "" Then Exit Function

    ' Split Source String (strSource) by SplitSeparator.
    vnt = Split(strSource, SplitSeparator)
    ' Assign the value of the last element in String Array (vnt)
    ' to Upper Bound String (strUB).
    strUB = vnt(UBound(vnt))

    ' Check if there is only one element in String Array (vnt). If so,
    ' write its value (strUB) to Resulting String (strResult) and go to
    ' ProcedureSuccess.
    If UBound(vnt) = 0 Then strResult = strUB: GoTo ProcedureSuccess

    ' Check if the length of Upper Bound String (strUB) is greater than
    ' NumberOfDigits. (UnTruncate = 0, by default)
    If Len(strUB) > NumberOfDigits Then Exit Function

    ' Add the needed number of TruncateStrings to Upper Bound String.
    strUB = strUB & String(NumberOfDigits - Len(strUB), TruncateString)

    ' Loop through the elements of String Array (vnt), from beginning
    ' to the element before the last, and concatenate them one after another
    ' to the Resulting String (strResult).
    For i = 0 To UBound(vnt) - 1: strResult = strResult & vnt(i): Next
    ' Add Upper Bound String (strUB) to the end of Resulting String (strResult).
    strResult = strResult & strUB

ProcedureSuccess:
    ' Convert Resulting String (strResult) to the resulting value of UnTruncate.
    UnTruncate = Val(strResult)

End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Но У меня такое чувство, что я упускаю некоторые важные моменты.

Я ищу другие решения: улучшение моей функции, формула Excel, решение Power Query, ... возможно, когда данные в Import столбец может быть цифрами или текстом.

Ответы [ 2 ]

2 голосов
/ 28 марта 2020

Это пример выдачи xhr для указанного вами URL и использования буфера обмена для копирования таблицы на лист. Номера отображаются как на странице. Вам нужно иметь некоторое представление о html или хотя бы знать, как щелкнуть правой кнопкой мыши элемент проверки (открывает вкладку элементов); щелкните правой кнопкой мыши копировать селектор на вкладке элементов инструментов разработчика - вы можете вставить этот селектор в html.querySelector("selector goes here").outerHTML; при условии выбора таблицы.

Public Sub GetVideoInfo()
    Dim xhr As Object, clipboard As Object, html As MSHTML.HTMLDocument 'required VBE > Tools > References > Microsoft HTML Object Library

    Set clipboard = GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
    Set xhr = CreateObject("MSXML2.XMLHTTP")
    Set html = New MSHTML.HTMLDocument

    With xhr
        .Open "GET", "https://kworb.net/youtube/", False
        .send
        html.body.innerHTML = .responseText
    End With
    clipboard.SetText html.querySelector("#youtuberealtime").outerHTML
    clipboard.PutInClipboard
    ActiveSheet.Cells(1, 1).PasteSpecial
End Sub
1 голос
/ 28 марта 2020

Похоже, вы использовали Legacy Wizard, а не Power Query.

Если вы используете Power Query, после выбора таблицы выберите Transform.

Затем, если столбец чисел был импортирован в виде текста и показывает разделитель цифр запятой, не удаляйте запятые. Скорее:

  • Щелкните правой кнопкой мыши заголовок столбца
  • В раскрывающемся меню правой кнопкой мыши:
    • Выберите Change Type --> Using Locale
    • Тип данных: Целое число

enter image description here

Это должно заботиться о вещах.

РЕДАКТИРОВАТЬ:

Что касается сохранения гиперссылок из веб-таблицы с помощью Power Query, это не так просто, как с Legacy Wizard, но вот метод, который, кажется, работает с вашим источником.

Требуется три запроса и функция. И вам нужно будет отредактировать таблицу после загрузки для форматирования чисел и возможных гиперссылок.

  • Запрос «Таблица 0» Загрузить веб-таблицу без ссылок
  • Запрос "getLinks" Загрузка ссылок, связанных с видео
  • Запрос "Merge1" Объединение двух вышеупомянутых запросов
  • Запрос fx " ExcelTrim " Реплицируйте обрезку Excel, чтобы иметь возможность сопоставлять имена видео в первых двух запросах, устраняя лишние пробелы между словами в заголовке видео.

ExcelTrim

Введите приведенный ниже код в расширенный редактор пустых запросов

let ExcelTrim = (TextToTrim) =>
    let
        ReplacedText = Text.Replace(TextToTrim, "  ", " "),
        Result = if not(Text.Contains(ReplacedText, "  "))
            then ReplacedText
                else @ExcelTrim(ReplacedText)
    in
        Text.Trim(Result)
in
    ExcelTrim

Таблица 0

Примечание I использовала функцию Changed Type with Locale, которая должна устранить проблему сброшенного нуля.

let
    Source = Web.Page(Web.Contents("https://kworb.net/youtube/")),
    Data = Source{0}[Data],
    #"Changed Type with Locale" = Table.TransformColumnTypes(Data, {{"Views", Int64.Type}, {"Likes", Int64.Type}}, "en-US"),
    #"Added Custom" = Table.AddColumn(#"Changed Type with Locale", "trimmedVideo", each ExcelTrim([Video]))
in
    #"Added Custom"

getLinks

let
    Source = Table.FromColumns({Lines.FromBinary(Web.Contents("https://kworb.net/youtube/"))}),
    #"Filtered Rows" = Table.SelectRows(Source, each Text.Contains([Column1], "href")),
    #"Filtered Rows1" = Table.SelectRows(#"Filtered Rows", each Text.Contains([Column1], "<div><a href=")),
    #"Added Custom" = Table.AddColumn(#"Filtered Rows1", "Link", each Text.BetweenDelimiters([Column1],"<a href=""","</a>")),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Added Custom", "Link", Splitter.SplitTextByEachDelimiter({""">"}, QuoteStyle.None, false), {"Link.1", "Link.2"}),
    #"Changed Type" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Link.1", type text}, {"Link.2", type text}}),
    #"Removed Columns" = Table.RemoveColumns(#"Changed Type",{"Column1"}),
    #"Added Custom1" = Table.AddColumn(#"Removed Columns", "trimmedVideo", each ExcelTrim([Link.2])),
    #"Added Custom2" = Table.AddColumn(#"Added Custom1", "normLinks", each if not Text.StartsWith([Link.1],"http") then 
    "https://kworb.net/youtube/" & [Link.1] else 
    [Link.1])
in
    #"Added Custom2"

Merge1

Returns ссылки в отдельном столбце из видео

let
    Source = Table.NestedJoin(#"Table 0", {"trimmedVideo"}, getLinks, {"trimmedVideo"}, "getLinks", JoinKind.LeftOuter),
    #"Added Custom" = Table.AddColumn(Source, "Links", each Table.Column([getLinks],"normLinks")),
    #"Extracted Values" = Table.TransformColumns(#"Added Custom", {"Links", each Text.Combine(List.Transform(_, Text.From)), type text}),
    #"Removed Columns" = Table.RemoveColumns(#"Extracted Values",{"trimmedVideo", "getLinks"})
in
    #"Removed Columns"

В качестве альтернативы вы можете использовать:

Merge1 (2)

Возвращает формулу HYPERLINK в таблицу, которая предоставляет интерактивную ссылку с понятным именем.

let
    Source = Table.NestedJoin(#"Table 0", {"trimmedVideo"}, getLinks, {"trimmedVideo"}, "getLinks", JoinKind.LeftOuter),
    #"Added Custom" = Table.AddColumn(Source, "Links", each Table.Column([getLinks],"normLinks")),
    #"Replaced Value" = Table.ReplaceValue(#"Added Custom","""","""""",Replacer.ReplaceText,{"Video"}),
    #"Extracted Values" = Table.TransformColumns(#"Replaced Value", {"Links", each Text.Combine(List.Transform(_, Text.From)), type text}),
    #"Removed Columns" = Table.RemoveColumns(#"Extracted Values",{"trimmedVideo", "getLinks"}),
    #"Added Custom1" = Table.AddColumn(#"Removed Columns", "Linked Videos", each "=HYPERLINK(""" & [Links] & """," & """" &[Video] & """)"),
    #"Changed Type" = Table.TransformColumnTypes(#"Added Custom1",{{"Linked Videos", type text}}),
    #"Removed Columns1" = Table.RemoveColumns(#"Changed Type",{"Video", "Links"}),
    #"Reordered Columns" = Table.ReorderColumns(#"Removed Columns1",{"", "2", "Linked Videos", "Views", "Likes"})
in
    #"Reordered Columns"

Если вы используете Merge1 (2) для получения гиперссылок, после сохранения вам нужно будет выбрать столбец Linked Video и выполнить Find/Replace или = с = чтобы превратить формулу из текстовой строки в формулу. Если вы измените sh запрос, вам нужно будет повторить этот процесс.

Вы также можете отформатировать столбцы Views и Likes, чтобы отобразить разделители тысяч.

Вот пример использования `Merge1 (2) с гиперссылками и моими разделителями тысяч.

enter image description here

...