问题
I have quite a conundrum which I have been trying to troubleshoot. I have a stored procedure in a MySql database, which I call through an Excel VBA application. The VBA application passes the recordset into an Array, and then I use a For Loop to place each of the items in the Array onto a worksheet.
Here's the problem: two of the values in the recordset keep coming back blank in Excel. Oddly, the two are in the middle of the Array, not the beginning or end. However, if I call the stored procedure through another query program such as HeidiSql, I receive ALL values back. I'm at a loss as to why I'm not receiving all of the values through Excel... or why the Array isn't receiving them all, at any rate.
Thanks in advance for your help.
Here is my code:
Sub StartHereFlexFunderCust()
On Error GoTo ErrorHandler
Dim Password As String
Dim SQLStr As String
'OMIT Dim Cn statement. Cn stands for Database Connection
Dim Server_Name As String
Dim User_ID As String
Dim Database_Name As String
Dim custID As String
Dim myArray()
'OMIT Dim rs statement. rs stands for Database Recordset and is the Recordset of what is returned
Set RS = CreateObject("ADODB.Recordset")
Server_Name = Range("O10").Value
Database_Name = Range("O11").Value ' Name of database
'id user or username. We need to write code to insert the current user into this variable (Application.Username) if possible. But they may not be consistent across all machines.
'For example mine is "Ryan Willging" and we would have to shorten it to rwillging but others may be rwillging.
'This is important because if we do not do this all queries will come from the same person and that is not good for debugging.
User_ID = Range("O12").Value
Password = Range("O13").Value
custID = Range("C4").Value 'Deal Number from Start here that we are passing into the stored procedure
'This is the storedprocedure call and it passes in the value of the DealId to the Stored Procedure
SQLStr = "call flexFundByCustomer(" + custID + ")"
Set cn = CreateObject("ADODB.Connection") 'NEW STATEMENT
'This statement takes the variables from the checklist and passes them into a connection string
cn.Open "Driver={MySQL ODBC 5.1 Driver};Server=" & _
Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
'This statement queries the database using the SQL string and the connection string.
'The adOpenStatic variable returns a static copy of a set of records that you can use to find data or generate reports. There are other variables that
'could be used but I think this one will suffice.
RS.Open SQLStr, cn, adOpenForwardOnly
Debug.Print msg 'or MsgBox msg
'Take all of the info from the queries and put them into the spreadsheet
myArray = RS.getrows()
Dim Fld_Name As String
Dim Val_of_Field As String
Dim starthere As Worksheet
Fld_Name = UBound(myArray, 1)
Val_of_Field = UBound(myArray, 2)
Set starthere = ThisWorkbook.Sheets("Start Here")
MsgBox "No error yet defined Start Here!"
'This little loop works well to dump the recordset into excel. We can then map the correct fields 'k inputs the headers and R inputs the rows returned in the Recordset
For K = 0 To Fld_Name ' By using a For loop the data is inputed into excel one row at a time
starthere.Range("U4").Offset(0, K).Value = RS.fields(K).Name
For R = 0 To Val_of_Field
starthere.Range("U4").Offset(R + 1, K).Value = myArray(K, R)
Next
Next
RS.Close
Set RS = Nothing
cn.Close
Set cn = Nothing
ErrorHandler:
MsgBox "There's been an error!"
Exit Sub
End Sub
回答1:
Consider using Range.CopyFromRecordset method to avoid any use of arrays. Or if memory does not allow, use a Do While Loop
across Recordset columns:
' COLUMN HEADERS
For i = 1 To RS.Fields.Count
starthere.("Results").Range("U4").Offset(0, i) = RS.Fields(i - 1).Name
Next i
' DATA ROWS
' COPYFROMRECORDSET APPROACH
starthere.Range("U5").CopyFromRecordset RS
' DO WHILE LOOP APPROACH
starthere.Activate
starthere.Range("U5").Activate
row = 5
Do While Not RS.EOF
For i = 0 To RS.Fields.Count - 1
ActiveCell.Offset(0, i) = RS.Fields(i)
Next i
row = row + 1
ActiveCell.Offset(row, 21)
RS.MoveNext
Loop
As for the values returning empty that may be a MySQL and Excel incompatibility of data types. For instance, you may have a table field set to MySQL's maximum decimal (65, 30) which denotes max digits of 65 and max 30 decimal points which cannot be reflected on a spreadsheet. Current precision limit of a cell value is 15 decimal points.
Alternatively, you may have a VARCHAR(65535)
which is the 65,535 byte limit or the open-ended TEXT
column of no limit that also cannot be displayed on spreadsheet. Current limit of characters in one cell is 32,767.
Try modifiying column to a smaller type:
ALTER TABLE `tableName` MODIFY COLUMN `largenumberfield` DECIMAL(10,7);
ALTER TABLE `tableName` MODIFY COLUMN `largetextfield` VARCHAR(255);
Why the other programs such as HeidiSQL retrieve values? It might be due to their internal conversion features forcing data values into a specific format (i.e., removing whitespaces, truncating values) which then renders adequately in Excel.
来源:https://stackoverflow.com/questions/38797258/excel-vba-array-not-receiving-all-values-from-stored-procedure-recordset-diffe