[英]VBA code leads to #value! in cell but works in immediate box
我编写了一个getprice函数,用于从Yahoo检索股票行情收录器,并从在线api检索比特币价格。 但是,比特币的代码会产生#value! 在我的Excel单元格中。 但是,当我从VB的立即框中运行该功能时,它的性能很好。 我感觉到这是某种兼容性问题,但我已经用尽了所有的故障排除知识。 任何帮助或指针,将不胜感激!
这是文件https://drive.google.com/file/d/0B-CQNUWfWnMzQTA5MW9Vb3NiLXc/view?usp=sharing
码:
Function GetPrice(strTicker As String, Optional dtDate As Variant)
Debug.Print "Getting Price..."
' Date is optional - if omitted, use today. If value is not a date, throw error.
If IsMissing(dtDate) Then
dtDate = Date
Else
If Not (IsDate(dtDate)) Then
GetPrice = CVErr(xlErrNum)
Debug.Print "Date problem!"
End If
End If
' Define variables
Dim dtPrevDate As Date
Dim strURL As String, strCSV As String, strDate As String, strRows() As String, strColumns() As String
Dim priceArray() As Variant
Dim wb As Workbook
Dim dbClose As Double
dbClose = 1 ' default for if price not found
' for stock tickers look at a weeks worth of data in case date is weekend
dtPrevDate = dtDate - 7
' Treat bitcoin separately and compile CSV with all BTC data
If strTicker = "BTCUSD" Then
' go to the URL
strURL = "https://api.bitcoinaverage.com/history/USD/per_day_all_time_history.csv"
priceArray = CsvToArray(strURL) 'convert to array
' Bitcoin date search
strDate = CStr(dtDate)
Debug.Print "Date: "; strDate
' side question but i dont understand why this vloopkup doesnt work???
'dbClose = Application.VLookup(DateValue(strDate), priceArray, 4, False) ' lookup value in column d
'try parsing array manually instead
For i = LBound(priceArray) To UBound(priceArray)
If CStr(priceArray(i, 1)) = strDate Then
dbClose = CDbl(priceArray(i, 4))
Exit For
Else
dbClose = 1
End If
Next i
' For all other tickers
' Compile the request URL with start date and end date
Else
Debug.Print "stock ticker:"; strTicker
strURL = "http://ichart.yahoo.com/table.csv?s=" & strTicker & _
"&a=" & Month(dtPrevDate) - 1 & _
"&b=" & Day(dtPrevDate) & _
"&c=" & Year(dtPrevDate) & _
"&d=" & Month(dtDate) - 1 & _
"&e=" & Day(dtDate) & _
"&f=" & Year(dtDate) & _
"&g=d&ignore=.csv"
' Declare an object as the http data
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", strURL, False
http.Send
strCSV = http.responseText
' The most recent information is in row 2, just below the table headings.
' The price close is the 5th entry
strRows() = Split(strCSV, Chr(10)) ' split the CSV into rows
strColumns = Split(strRows(1), ",") ' split the relevant row into columns. 1 means 2nd row, starting at index 0
dbClose = strColumns(4) ' 4 means: 5th position, starting at index 0
End If
If dbClose = 1 Then
GetPrice = "Not Found"
Debug.Print "GetPrice"; GetPrice
Else
GetPrice = dbClose
Debug.Print "Price: "; GetPrice
End If
Set http = Nothing
End Function
Function CsvToArray(filepath As String) As Variant
Dim wb As Workbook
Dim array1() As Variant
Application.ScreenUpdating = False
Set wb = Workbooks.Open(filepath)
' THIS LINE SEEMS TO CAUSE THE PROBLEM
array1 = wb.Sheets(1).Range("A1").CurrentRegion.Value
wb.Close False
CsvToArray = array1
Application.ScreenUpdating = True
End Function
我认为您无法以尝试的方式访问比特币网址。 Excel实际上无法触发文件下载&,而您试图用于CsvToArray方法的文件路径没有任何意义。
相反,请尝试以下方法(您将需要一些其他逻辑来找到所需的比特币日期,但这应将您带往正确的方向:
Function GetPrice(strTicker As String, Optional dtDate As Variant)
Debug.Print "Getting Price..."
' Date is optional - if omitted, use today. If value is not a date, throw error.
If IsMissing(dtDate) Then
dtDate = Date
Else
If Not (IsDate(dtDate)) Then
GetPrice = CVErr(xlErrNum)
Debug.Print "Date problem!"
End If
End If
' Define variables
Dim dtPrevDate As Date
Dim strURL As String, strCSV As String, strDate As String, strRows() As String, strColumns() As String
Dim priceArray() As Variant
Dim wb As Workbook
Dim dbClose As Double
Dim desiredRow, desiredCol as Long
dbClose = 1 ' default for if price not found
' for stock tickers look at a weeks worth of data in case date is weekend
dtPrevDate = dtDate - 7
' Treat bitcoin separately and compile CSV with all BTC data
If strTicker = "BTCUSD" Then
' go to the URL
strURL = "https://api.bitcoinaverage.com/history/USD/per_day_all_time_history.csv"
' For all other tickers
' Compile the request URL with start date and end date
Else
Debug.Print "stock ticker:"; strTicker
strURL = "http://ichart.yahoo.com/table.csv?s=" & strTicker & _
"&a=" & Month(dtPrevDate) - 1 & _
"&b=" & Day(dtPrevDate) & _
"&c=" & Year(dtPrevDate) & _
"&d=" & Month(dtDate) - 1 & _
"&e=" & Day(dtDate) & _
"&f=" & Year(dtDate) & _
"&g=d&ignore=.csv"
End If
' Declare an object as the http data
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", strURL, False
http.Send
strCSV = http.responseText
' The most recent information is in row 2, just below the table headings.
' The price close is the 5th entry
strRows() = Split(strCSV, Chr(10)) ' split the CSV into rows
If strTicker = "BTCUSD" Then
'ADD LOGIC HERE TO FIND DESIRED DATE
desiredRow = UBound(strRows)
desiredCol = 2
Else
desiredRow = 2
desiredCol = 5
End If
strColumns = Split(strRows(desiredRow - 1), ",") ' split the relevant row into columns. 1 means 2nd row, starting at index 0
dbClose = strColumns(desiredCol - 1) ' 4 means: 5th position, starting at index 0
If dbClose = 1 Then
GetPrice = "Not Found"
Debug.Print "GetPrice"; GetPrice
Else
GetPrice = dbClose
Debug.Print "Price: "; GetPrice
End If
Set http = Nothing
End Function
修复代码
Function GetPrice(strTicker As String, Optional dtDate As Variant)
Debug.Print "Getting Price..."
' Date is optional - if omitted, use today. If value is not a date, throw error.
If IsMissing(dtDate) Then
dtDate = Date
Else
If Not (IsDate(dtDate)) Then
GetPrice = CVErr(xlErrNum)
Debug.Print "Date problem!"
End If
End If
' Define variables
Dim dtPrevDate As Date
Dim strURL As String, strCSV As String, strDate As String, strRows() As String, strColumns() As String
Dim priceArray() As Variant
Dim wb As Workbook
Dim dbClose As Double
dbClose = 1 ' default for if price not found
' for stock tickers look at a weeks worth of data in case date is weekend
dtPrevDate = dtDate - 7
' Treat bitcoin separately and compile CSV with all BTC data
If strTicker = "BTCUSD" Then
' go to the URL
strURL = "https://api.bitcoinaverage.com/history/USD/per_day_all_time_history.csv"
'priceArray = CsvToArray(strURL) 'convert to array
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", strURL, False
http.Send
strCSV = http.responseText
'split csv into rows
strRows() = Split(strCSV, Chr(10))
' Bitcoin date search
numDate = CDate(dtDate)
Debug.Print "Date: "; CStr(dtDate)
'compare dates in strCSV to dtDate
For i = 1 To UBound(strRows())
rowInfo = Split(strRows(i), ",") 'divide the rows by commas
rowDate = Split(rowInfo(0), " ") 'look at the date/time and take the date only
rowDate = CDate(rowDate(0)) 'convert the date from string to CDate
If rowDate >= numDate Then 'Make the comparison
dbClose = CDbl(rowInfo(3)) 'set the price as daily avg
Exit For 'exit for loop
Else
dbClose = 1
End If
Next i
' For all other tickers
' Compile the request URL with start date and end date
Else
Debug.Print "stock ticker:"; strTicker
strURL = "http://ichart.yahoo.com/table.csv?s=" & strTicker & _
"&a=" & Month(dtPrevDate) - 1 & _
"&b=" & Day(dtPrevDate) & _
"&c=" & Year(dtPrevDate) & _
"&d=" & Month(dtDate) - 1 & _
"&e=" & Day(dtDate) & _
"&f=" & Year(dtDate) & _
"&g=d&ignore=.csv"
' Declare an object as the http data
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", strURL, False
http.Send
strCSV = http.responseText
' The most recent information is in row 2, just below the table headings.
' The price close is the 5th entry
strRows() = Split(strCSV, Chr(10)) ' split the CSV into rows
strColumns = Split(strRows(1), ",") ' split the relevant row into columns. 1 means 2nd row, starting at index 0
dbClose = strColumns(4) ' 4 means: 5th position, starting at index 0
End If
If dbClose = 1 Then
GetPrice = 1
Debug.Print "GetPrice"; GetPrice
Else
GetPrice = dbClose
Debug.Print "Price: "; GetPrice
End If
Set http = Nothing
End Function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.