2016-08-10 1 views
0

Comme le titre le suggère, je suis en train de chercher différentes façons de stocker le contenu d'une requête dans un tableau. J'ai expérimenté avec différentes variétés de faire cela, mais il semble que la plupart de ces façons sont correctes dans leur sortie. Ceci est bien sûr dû à mon manque de compréhension de la façon dont cela est censé être fait de manière appropriée, donc après un certain temps d'expérimentation, j'ai décidé de demander quelle est la meilleure approche pour cela? Je vais partager avec vous certaines de mes approches jusqu'à présent et vous pouvez voir où mon enquête m'a atterri.SQL Query to VBA Array

Dim MyArray() As Variant 
MyArray = rst.GetRows(rst.RecordCount) 

C'était ok encore ce stocké toutes les informations verticalement au lieu de horizontalement. Y a-t-il un moyen de renverser ça? Serait-ce à travers l'utilisation de ReDim? Ou est-ce dû au fait que les lignes sont stockées dans des dimensions de tableau et donc naturellement verticales?

 Index = 0 
     Do While Not rst.EOF 
       ReDim Preserve MyArray(1, Index) 
       MyArray(0, Index) = CStr(rst.Fields(0).Value) 

       'Safety check to make sure the value isn't null (was having problems before) 
       If rst.Fields(1).Value <> vbNullString Then 
        MyArray(1, Index) = CStr(rst.Fields(1).Value) 
       End If 
      Index = Index + 1 
      rst.MoveNext 
     Loop 

     sheet.Range("a1:ba10000").Value = MyArray 

Cette choses encore stockées verticalement, mais la sortie na pas correctement les enregistrements, et en fait que tirer les deux premières colonnes d'information par enregistrement, le reste était sortie comme # N/A #. Je pense que j'étais plus proche de mon approche originale, mais j'ai décidé que l'expérimentation pourrait me mener quelque part.

Avez-vous des suggestions ou pouvez-vous me diriger dans la bonne direction?

Répondre

3

Je pense qu'il serait plus rapide à vider juste les résultats à la feuille en utilisant:

Sheet1.Range("A1").CopyFromRecordset rst 

Et puis stocker les résultats de cette décharge (de la gamme) dans un tableau. Si elle n'est pas verticale ou horizontale comme vous le souhaitez, une transposition spéciale copier/coller-special en fera un travail très rapide, avant de la ramener dans le tableau. Je suggère simplement que, comme il semble que votre jeu d'enregistrements soit plutôt volumineux (2x10000), l'itération de votre jeu va prendre beaucoup de temps, vous devrez alors décharger les résultats dans la feuille de calcul, les manipuler et les récupérer devrait être très très rapide.


Je travaille avec beaucoup ADODB RecordSets dans Excel, j'ai donc un module que je viens importer dans une feuille où je vais être connecter à une base de données. C'est un sous-programme que j'utilise où je l'envoie juste le SQL, une gamme à laquelle il devrait laisser tomber les données et un drapeau s'il devrait également laisser tomber les en-têtes, et si la fonction devrait ou non gérer la connexion. Ce dernier indicateur correspond au moment où je souhaite ouvrir une connexion, émettre plusieurs instructions SQL, puis le fermer. Sinon, cela ne fait que s'ouvrir, exécute le SQL et se ferme.

Sub getData(strSQL As String, rngDrop As Range, Optional includeHeaders As Boolean = False, Optional handleConnection As Boolean = True) 

    Dim rs As New ADODB.Recordset 

    'Little error handling 
    On Error GoTo errHandler 

    'Open the database (seperate function for creating the connection object) 
    If handleConnection Then openConnection 

    'set up the recordset 
    rs.ActiveConnection = adoConn 
    rs.LockType = adLockOptimistic 
    rs.CursorLocation = adOpenKeyset 
    rs.Open strSQL 

    'check for data 
    If rs.EOF And rs.BOF Then 
     Debug.Print "No data returned. Boo." 
     Debug.Print " Offending SQL:" 
     Debug.Print "---------------------------" 
     Debug.Print strSQL 
     Debug.Print "---------------------------" 
    End If 

    'clear the range 
    rngDrop.ClearContents 

    'If the headers are requested, then dump those and offset(1) to dump the data 
    If includeHeaders Then 
     Dim header As field 
     Dim intCol As Integer: intCol = 0 

     For Each header In rs.Fields 
      rngDrop.Cells(1, 1).Offset(0, intCol).value = header.Name 
      intCol = intCol + 1 
     Next header 
     rngDrop.Cells(1, 1).Offset(1, 0).CopyFromRecordset rs 
    Else 
     'otherwise just dump the recordset 
     rngDrop.CopyFromRecordset rs 
    End If 

    'clean up 
    rs.Close 
    If handleConnection Then adoConn.Close 
    Exit Sub 
errHandler: 
    Debug.Print Err.description, vbCritical, "Error " & Err.Number 
End Sub 

J'utilise dynamic named ranges pour la plage que je passe dans cette fonction afin que je puisse décharge rapide et référencer les données dans la feuille de calcul. De cette façon, la plage dans laquelle nous déposons les données augmente/diminue avec les données qui y sont déposées. Donc, aller chercher des données, avec un en-tête, BOLDING l'en-tête, puis copier et le transposer ailleurs, et coller finalement dans un tableau ressemblerait à ceci:

Sub test() 
    getData("Select f1, f2 FROM table;", Range("MyNamedRange"), True) 
    Range("MyNamedRange").Rows(1).Font.Bold = True 
    Range("MyNamedRange").Copy 
    Sheet2.Range("A1").pasteSpecial Transpose:=True 
    Arr = Sheet2.Range("A1").Resize(Range("myNAmedRange).columns.count, Range("MyNamedRange").Rows.Count) 
End Sub 

Cela pourrait probablement être nettoyé un peu, mais il devrait travailler et ça devrait être plutôt rapide.

+0

Si vous voulez les en-têtes, coller à '" A2 "' et ajouter ce qui suit: 'Avec ThisWorkbook.Sheets (1) Set Range1 = .Range (.Cellules (1, 1), .Cells (1, rst .Fields.Count)) Pour chaque cellule1 dans la plage1 Cell1.Value = rst.Fields (Cell1.Column - 1).Nom Cell1.Font.Bold = True Suivant Cell1 Fin With' – puzzlepiece87

+1

Voir je faisais ça avant et je suis maintenant dans la phase expérimentale où je tente et d'améliorer les performances, mais vous le faire sonner comme son « 6 d'un, une demi-douzaine de l'autre "où les compromis ne valent pas vraiment beaucoup. –

+0

Il semble sorte de kludgey pour vider les enregistrements dans la feuille de calcul, manipuler, puis le reprendre dans votre tableau pour faire tout ce que vous allez faire, mais ... votre jeu de résultats est grande, et la transformation des données dans un gamme est ce que Excel ... excelle à ... Alors je voudrais juste laisser faire c'est chose. – JNevill