问题
While importing data from the web in Excel 2019 choosing Data>Get Data>From Other Sources>From Web
, the last (trailing) zeros of numbers are being truncated resulting in the following 'Import' column:
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
I would like to convert the data which is text (commas, periods are remaining thousands separators), to numbers like in the Desired column.
I've overdone the following working VBA function:
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
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
But I have a feeling I'm missing some important points.
I'm looking for other solutions: an improvement of my function, an Excel formula, a Power Query Solution, ... possibly when the data in Import column could be numbers or text.
回答1:
It seems you were using the Legacy Wizard rather than Power Query.
If you use Power Query, after selecting the Table, select Transform
.
Then, if the number column has been imported as text, and is showing the digits separator of the comma, don't remove the commas. Rather:
- Right Click on the Column Header
- From the Right-Click dropdown menu:
- Select
Change Type --> Using Locale
- Data type: Whole Number
- Select
That should take care of things.
EDIT:
With regard to retaining hyperlinks from a web table using Power Query, it is not as straightforward as with the Legacy Wizard, but here is a method that seems to work with your source.
It requires three queries and a function. And you will need to edit the table after the download to format the numbers, and possible the hyperlinks.
- Query "Table 0" Download the web table without links
- Query "getLinks" Download the links associated with the Videos
- Query "Merge1" Merge the two queries above
- Query fx"ExcelTrim" Replicate Excel's trim so as to be able to match the video names in the first two queries, by eliminating excess spaces between words in the video title.
ExcelTrim
Enter the code below into the Advanced Editor of a Blank Query
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
Table 0
Note I used the Changed Type with Locale
feature which should eliminate your dropped zero's problem.
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 the links in a separate column from the Videos
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"
Alternatively you can use:
Merge1 (2)
Returns a HYPERLINK
formula to the table which provides a clickable link with a friendly name.
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"
If you use Merge1 (2) to get the hyperlinks, after saving, you will need to select the Linked Video
column, and do a Find/Replace
or =
with =
in order to turn the formula from a text string into a formula. If you refresh the query, you will need to repeat this process.
You may also want to format the Views
and Likes
columns to show your thousands separators.
Here is an example using `Merge1 (2) with the hyperlinks and my thousands separators.
回答2:
This is an example of issuing an xhr to the url you mentioned and using clipboard to copy table to sheet. Numbers appear as on page. You do need to have some familiarity with html or at least know how to right click inspect element (opens elements tab); right click copy selector in dev tools elements tab - you can then paste that selector into html.querySelector("selector goes here").outerHTML
; assuming selecting a table.
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
来源:https://stackoverflow.com/questions/60902093/last-zeros-truncated-when-getting-external-data