【问题标题】:Splitting Text By Rows and Columns按行和列拆分文本
【发布时间】:2016-02-11 19:28:57
【问题描述】:

我正在使用 Excel 宏从 Yahoo Finance 检索 CSV 文件。在 A 列中,我将股票代码列为输入。我曾经运行一个宏,将每个代码插入 URL,然后将结果输出到 B 列。然后我会调用一个函数将 B 列中的文本拆分为 B 列到 E 列。

当我创建一个连接的 URL 字符串并只调用一次 URL 时,该函数变得更快。主要问题是我收到以下格式的数据:

"81.950,342.05B,"Exxon Mobil Corporation Common ",263.71B
81.38,201.29B,"Alibaba Group Holding Limited A",13.56B
754.77,519.78B,"Alphabet Inc.",71.76B
120.57,649.30B,"Apple Inc.",233.72B"

电流输出

预期/理想输出

当我一次调用一个 URL 时,我可以使用 Text to Columns 函数分离出必要的数据。现在我需要它按列和行分隔。

Sub StockDataPull() 
Dim url As String
Dim http As Object
Dim LastRow As Long
Dim Symbol_rng As Range
Dim Output_rng As Range

'Define Last Row in Ticker Range
    With ActiveSheet
        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With

    Application.ScreenUpdating = False

Set Symbol_rng = Range("A5:A" & LastRow).Cells
Set Output_rng = Range("C5:F" & LastRow).Cells

    'Open Yahoo Finance URL
        url = "http://download.finance.yahoo.com/d/quotes.csv?s=" & concatRange(Symbol_rng) & "&f=pj1ns6"
                Set http = CreateObject("MSXML2.XMLHTTP")
        http.Open "GET", url, False
        http.Send
                    Output_rng = http.responseText
           Set http = Nothing
    Application.DisplayAlerts = False
    Application.ScreenUpdating = True
End Sub


'The code below is what I used before Sub StockDataPull(). This code calls a URL for each ticker, instead of one URL for all tickers in a concatenated string. It's considerably slower, but it works because it outputs the data two cells away from the ticker, then I call Sub Delimiter() to separate it across the next few consecutive columns.


Sub StockData()
Dim url As String
Dim http As Object
Dim LastRow As Long
Dim Symbol_rng As Range

''Define Last Row in Ticker Range
    With ActiveSheet
        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With

    Application.ScreenUpdating = False

Set Symbol_rng = Range("A5:A" & LastRow).Cells

    For Each cell In Symbol_rng

    ''Open Yahoo Finance URL
        url = "http://download.finance.yahoo.com/d/quotes.csv?s=" & cell.Value & "&f=pj1ns6"

        Set http = CreateObject("MSXML2.XMLHTTP")
        http.Open "GET", url, False
        http.Send

        cell.Offset(rowOffset:=0, columnOffset:=2) = http.responseText

        Set http = Nothing

    Next cell

        Application.DisplayAlerts = False    
        Application.ScreenUpdating = True    
        Call Delimiter            
    End Sub

Sub Delimiter()    
''Define Last Row in Ticker Range
    With ActiveSheet
        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With

''Separate the data into four columns
    Range("C5:C" & LastRow).TextToColumns Destination:=Range("C5"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
        Semicolon:=False, Comma:=True, Space:=False, Other:=False, FieldInfo _
        :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1)), TrailingMinusNumbers:=True

''Unwrap the text
    Range("C5:F" & LastRow).Select
    With Selection
        .WrapText = False
    End With

End Sub

【问题讨论】:

  • 哪里出了问题?
  • 您还可以发布预期输出的示例表吗?不过好像@GSazheniuk 有气味了,看Split
  • 谢谢,我确实看过拆分功能。我可以使用它将输出数据分成列;我只是不知道如何将它放入行中。
  • 如果有代码可以分栏,可以发一下吗?应该只需要稍微调整一下就可以放入行中。

标签: vba excel split delimiter


【解决方案1】:

我知道这不是处理此类问题的最佳方法,但应该可以。

首先,我们需要更改您的Delimiter sub(这很好!),以便它可以处理从响应中提取的行:

Sub Delimiter(ByVal LastRow)
''Separate the data into four columns
    Range("B1:B" & LastRow).TextToColumns Destination:=Range("C1:C" & LastRow), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
        Semicolon:=False, Comma:=True, Space:=False, Other:=False, FieldInfo _
        :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1)), TrailingMinusNumbers:=True

''Unwrap the text
    Range("B1:F" & LastRow).Select
    With Selection
        .WrapText = False
    End With

End Sub

以下是如何以正确的方式拆分您的回复:

Sub SplitToLines()
    s = Cells(1, "A")
    If Left(s, 1) = """" Then
        s = Mid(s, 2)
    End If

    If Right(s, 1) = """" Then
        s = Mid(s, 1, Len(s) - 1)
    End If

    resLines = Split(s, vbLf)

    For i = LBound(resLines) To UBound(resLines)
        Cells(i + 1, "B") = resLines(i)
    Next i
    Delimiter (i + 1)

End Sub

我刚刚检查了您的示例,它有效。您只需将您的回复放在“A1”单元格中(或更改宏)。

如果您遇到问题,请告诉我。

【讨论】:

  • 非常感谢!这对我来说是一个巨大的帮助。我修改了代码以澄清输出范围(我意识到我复制的代码与我在原始问题中指定的输出相矛盾)但我遇到了一个小问题。除了最后两个之外,所有行和列都在重新格式化。即使我添加到代码范围内,它也会排除最后两行。
  • 您能否提供有关您的问题的更多详细信息?我没有得到这部分“所有行和列都在重新格式化,除了最后两个。”
  • 我希望我能解释更多。此代码按列和行分隔数据,这正是我需要它做的。问题是它停在最后两行。从 URL 调用的所有数据都包含在表格最后两行的每个单元格中。
  • 抱歉一直打扰你。您可以编辑分割线和分隔符代码,使输出范围从 C5 开始吗?代码输入位于 A5:LastRow 中,数据输出应来自 C5:FLastRow。再次感谢
【解决方案2】:

热心的 VB 新手提醒。

Private Sub so_stub_1()
 'wsSo is the name of my test worksheet
  Dim hdr() As String: hdr = Split("Last Close Price, Market Cap, Company Name, Annual Revenue", ",")
  Dim data() As Variant: data = wsSO.Range("G1:G4")
  Dim i As Integer
  Dim r As Integer
  For i = 1 To UBound(data) 
    r = i + 1 'offset in my test sheet
    wsSO.Range("A" & r & ":D" & r) = Split(data(i, 1), ",")
 Next 'i 
End Sub

【讨论】:

  • 非常感谢。感谢您的帮助 - 以及贬低的警告。
  • @JMoore 确保警报是对我的引用!
  • 哈哈哦!好吧,你本可以愚弄我的。我绝对是热心的新手
【解决方案3】:

我不确定你需要什么,但你可以尝试用这个函数提取你需要的字符串

Function ExtractText(ByVal Txt As String) As String
    Txt = Right(Txt, Len(Txt) - InStr(1, Txt, ",""", vbTextCompare) - 1)
    Txt = Left(Txt, InStr(1, Txt, """,", vbTextCompare) - 1)
End Function

这会从您在表中获得的原始字符串中提取公司名称。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    相关资源
    最近更新 更多