Excel VBA Array not receiving all values from stored procedure recordset - different result than running stored procedure outside of Excel

放肆的年华 提交于 2020-01-15 06:53:56

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!