Requetes SQL dynamiques et paramètres dynamiques

Bonsoir à tous,

Je me permets de solliciter votre aide afin de finaliser un de mes projets.

Je dois alimenter une feuille excel avec les résultats de requêtes SQL dont les paramètres se situent dans un tableau annexe.

Ma problématique vient du fait que le nombre de requetes SQL a effectuer doit etre dynamique et que je dois boucler sur les paramètres contenu dans le tableau.

A ce jour, je duplique autant de fois le code et les variables qui constituent la requete qu'il y a de lignes dans la tableau de paramétrage.

Je n'arrive pas à conceptualiser le tableau et les différentes boucles afin d'automatiser définitivement l’exécution de requête SQL et ce quelque soit le nombre

Voici le tableau de paramétrage des requetes qui se présente sous cette forme, 3 lignes de paramétrage à l'occurence.

NomRapport TableA TableB Champ1 Champ2 Champ3

Rapport21 CLIENTS_21 RDV_21 ville tel_cli adresse_email

Rapport71 CLIENTS_71 RDV_71 commune telephone mail

Rapport69 CLIENTS_69 RDV_69 city tel email

Ci-dessous mon code VBA que j'ai simplifié , vous remarquerez que je dois dupliquer autant de fois le code de la construction de la requête et de son exécution qu'l pourra en avoir dans le tableau des paramétrés

Sub GenererStats()

Dim ServeurSQL As String

Dim LoginSQL As String

Dim PasswordSQL As String

Dim BaseSQL As String

Dim TableAppels As String

Dim TableClients As String

Dim rs1 As String

Dim i, j, r As String

Dim Rapport1, Rapport2, Rapport3 As String

Dim TableA1, TableA2, TableA3 As String

Dim TableB1, TableB2, TableB3 As String

Dim Champ1A, Champ1B, Champs1C As String

Dim Champ2A, Champ2B, Champs2C As String

Dim Champ3A, Champ3B, Champs3C As String

Dim rs As ADODB.Recordset

Dim cn As ADODB.Connection

Set cn = New ADODB.Connection

Set rs = New ADODB.Recordset

'connexion sql serveur

cn.ConnectionString = "provider=sqloledb.1;data source=" & ServeurSQL & ";user id='" & LoginSQL & "';password= '" & PasswordSQL & "';initial catalog= '" & BaseSQL & "'"

cn.Open

rs.ActiveConnection = cn

'parametre requete 1

Rapport1 = Sheet("liste").Range("A2").Value

TableA1 = Sheet("liste").Range("B2").Value

TableB1 = Sheet("liste").Range("C2").Value

Champ1A = Sheet("liste").Range("D2").Value

Champ2A = Sheet("liste").Range("E2").Value

Champ3A = Sheet("liste").Range("F2").Value

'parametre requete 2

Rapport2 = Sheet("liste").Range("A3").Value

TableA2 = Sheet("liste").Range("B3").Value

TableB2 = Sheet("liste").Range("C3").Value

Champ1B = Sheet("liste").Range("D3").Value

Champ2B = Sheet("liste").Range("E3").Value

Champ3B = Sheet("liste").Range("F3").Value

'modele requete sql

rs1 = "SELECT 'Rapport' AS NOM_RAPPORT, TableB.VILLE, TableB.TEL, TableB.EMAIL, "

rs1 = rs1 + "COUNT(CASE WHEN TableA.STATUS = 'RDV') THEN 1 ELSE NULL END) AS NB_RDV, "

rs1 = rs1 + "COUNT(TableA.INDICE) AS NB_FICHE "

rs1 = rs1 + "FROM TableA INNER JOIN TableB ON TableA.ID = TableB.ID "

rs1 = rs1 + "GROUP BY TableB.VILLE, TableB.TEL, TableB.EMAIL "

Sheets("consolidation").Select

Cells.Select

Selection.ClearContents

'execution rapport 1 du tableau

If Rapport1 <> "" Then

rs2 = Replace(rs1, "TableA", "" & TableA1 & "")

rs2 = Replace(rs2, "TableB", "" & TableB1 & "")

rs2 = Replace(rs2, "Rapport", "" & Rapport1 & "")

rs2 = Replace(rs2, "Champ1", "" & Champ1A & "")

rs2 = Replace(rs2, "Champ2", "" & Champ2A & "")

rs2 = Replace(rs2, "Champ3", "" & Champ3A & "")

rs.Open rs2

For i = 0 To rs.Fields.Count - 1

Cells(1, i + 1) = rs.Fields(i).Name

Cells(1, i + 1).Interior.ColorIndex = 15

Next

'ligne de départ

r = 2

Do While Not rs.EOF

For j = 0 To rs.Fields.Count - 1

Cells(r, j + 1) = rs.Fields(j)

Next j

rs.MoveNext

r = r + 1

Loop

rs.Close

End If

'execution rapport 2 du tableau

If Rapport2 <> "" Then

rs2 = Replace(rs1, "TableA", "" & TableA2 & "")

rs2 = Replace(rs2, "TableB", "" & TableB2 & "")

rs2 = Replace(rs2, "Rapport", "" & Rapport2 & "")

rs2 = Replace(rs2, "Champ1", "" & Champ1B & "")

rs2 = Replace(rs2, "Champ2", "" & Champ2B & "")

rs2 = Replace(rs2, "Champ3", "" & Champ3B & "")

rs.Open rs2

Do While Not rs.EOF

For j = 0 To rs.Fields.Count - 1

Cells(r, j + 1) = rs.Fields(j)

Next j

rs.MoveNext

r = r + 1

Loop

rs.Close

End If

End Sub

Pouvez-vous donc s'il vous plaît m' orienter sur la démarche et la structure à créer et à mettre en place afin de rendre ce code totalement dynamique.

En espérant avoir été explicite, je vous remercie par avance pour votre aide.

Bonne soirée.

Bonjour,

Un truc dans le genre ? Surement à adapter encore mais c'est une piste :

Sub GenererStats()

    Dim ServeurSQL As String
    Dim LoginSQL As String
    Dim PasswordSQL As String
    Dim BaseSQL As String
    Dim TableAppels As String
    Dim TableClients As String
    Dim SQL As String
    Dim i, j, r As String
    Dim TableA As String
    Dim TableB As String
    Dim Rapport As String
    Dim Rapport1, Rapport2, Rapport3 As String '<---attention, seul Rapport3 est typé "String", les deux autres sont typés "Variant"
    'Dim Champ1A, Champ1B, Champs1C As String
    'Dim Champ2A, Champ2B, Champs2C As String
    'Dim Champ3A, Champ3B, Champs3C As String
    Dim RS As ADODB.Recordset
    Dim CN As ADODB.Connection

    Set CN = New ADODB.Connection
    Set RS = New ADODB.Recordset

    ' Pas initialisé ?!
    '---> ServeurSQL
    '---> LoginSQL
    '---> PasswordSQL
    '---> BaseSQL

    'connexion sql serveur
    CN.ConnectionString = "provider=sqloledb.1;data source=" & ServeurSQL & ";user id='" & LoginSQL & "';password= '" & PasswordSQL & "';initial catalog= '" & BaseSQL & "'"
    CN.Open
    RS.ActiveConnection = CN

    Sheets("consolidation").Select
    Cells.Select
    Selection.ClearContents

    Rapport = Sheet("liste").Range("A2").Value
    TableA = Sheet("liste").Range("B2").Value
    TableB = Sheet("liste").Range("C2").Value

    If Rapport <> "" Then

        SQL = "SELECT '" & Rapport & "' AS NOM_RAPPORT, " & TableB & ".VILLE, " & TableB & ".TEL, " & TableB & ".EMAIL, "
        SQL = SQL & "COUNT(CASE WHEN " & TableA & ".STATUS = 'RDV') THEN 1 ELSE NULL END) AS NB_RDV, "
        SQL = SQL & "COUNT(" & TableA & ".INDICE) AS NB_FICHE "
        SQL = SQL & "FROM " & TableA & " INNER JOIN " & TableB & " ON " & TableA & ".ID = " & TableB & ".ID "
        SQL = SQL & "GROUP BY " & TableB & ".VILLE, " & TableB & ".TEL, " & TableB & ".EMAIL "

       RS.Open SQL

        For i = 0 To RS.Fields.Count - 1
            Cells(1, i + 1) = RS.Fields(i).Name
            Cells(1, i + 1).Interior.ColorIndex = 15
        Next

        'ligne de départ
        r = 2

        Do While Not RS.EOF

            For j = 0 To RS.Fields.Count - 1: Cells(r, j + 1) = RS.Fields(j): Next j

            RS.MoveNext
            r = r + 1

        Loop

        RS.Close

    End If

    Rapport = Sheet("liste").Range("A3").Value
    TableA = Sheet("liste").Range("B3").Value
    TableB = Sheet("liste").Range("C3").Value

    'execution rapport 2 du tableau
    If Rapport <> "" Then

        SQL = "SELECT '" & Rapport & "' AS NOM_RAPPORT, " & TableB & ".VILLE, " & TableB & ".TEL, " & TableB & ".EMAIL, "
        SQL = SQL & "COUNT(CASE WHEN " & TableA & ".STATUS = 'RDV') THEN 1 ELSE NULL END) AS NB_RDV, "
        SQL = SQL & "COUNT(" & TableA & ".INDICE) AS NB_FICHE "
        SQL = SQL & "FROM " & TableA & " INNER JOIN " & TableB & " ON " & TableA & ".ID = " & TableB & ".ID "
        SQL = SQL & "GROUP BY " & TableB & ".VILLE, " & TableB & ".TEL, " & TableB & ".EMAIL "

        RS.Open SQL

        Do While Not RS.EOF

            For j = 0 To RS.Fields.Count - 1: Cells(r, j + 1) = RS.Fields(j): Next j

            RS.MoveNext
            r = r + 1

        Loop

        RS.Close

    End If

End Sub

Finalement, voici mon code pour executer autant de requetes sql que l'on souhaite en fonction des parametres renseignées dans un tableau.

A adapter en fonction des besoins

Option Explicit
Option Base 1
Sub GenererReqDyn()
'Declaration des variables
'Appel de la fonction de connexion au serveur SQL :
ConnexionSQL
rs.ActiveConnection = cn
'Requete SQL :
rs1 = "SELECT 'NomCampagne' AS NOM_CAMPAGNE, TableClients.CodeAff, TableClients.NomAff, TableClients.MarqueAff, "
rs1 = rs1 + "COUNT(CASE  WHEN TableAppels.STATUS IN (1) THEN 1 ELSE NULL END) AS RDV, "
rs1 = rs1 + "FROM TableAppels INNER JOIN TableClients ON TableAppels.INDICE = TableClients.INDICE "
rs1 = rs1 + "GROUP BY TableClients.CodeAff, TableClients.NomAff, TableClients.MarqueAff "

'on vide la feuille cible
Sheets("cible").Select
Cells.Select
Selection.ClearContents

'initialisation du tableal
Sheets("Tableau").Select
Montab = Sheets("Tableau").Range("A1:H500").Value

'position du premier resultat de la requete
r = 2

For i = LBound(Montab, 1) To UBound(Montab, 1)
'Affectation des valeurs du tableau
    NomCampagne01 = Montab(i, 1)
'Sortie de la boucle si non renseignée
    If NomCampagne01 = "" Then Exit For
        TableAppels01 = Montab(i, 2)
        TableClients01 = Montab(i, 3)
        CodeAff01 = Montab(i, 4)
        NomAff01 = Montab(i, 5)
        MarqueAff01 = Montab(i, 6)

'Remplacement des critères de la requete SQL par celles du tableau
    rs2 = Replace(rs1, "TableAppels", "" & TableAppels01 & "")
    rs2 = Replace(rs2, "TableClients", "" & TableClients01 & "")
    rs2 = Replace(rs2, "NomCampagne", "" & NomCampagne01 & "")
    rs2 = Replace(rs2, "CodeAff", "" & CodeAff01 & "")
    rs2 = Replace(rs2, "NomAff", "" & NomAff01 & "")
    rs2 = Replace(rs2, "MarqueAff", "" & MarqueAff01 & "")

'selection de la feuille cible
Sheets("cible").Select
'execution de la requete SQL
rs.Open rs2

'Initialisation de la 1ere ligne
If Cells(1, 1) = "" Then
    For j = 0 To rs.Fields.Count - 1
        Cells(1, j + 1) = rs.Fields(j).Name
        Cells(1, j + 1).Interior.ColorIndex = 15
    Next
End If

'Execution requete SQL et remplissage
Do While Not rs.EOF
    For k = 0 To rs.Fields.Count - 1
        Cells(r, k + 1) = rs.Fields(k)
    Next k
    rs.MoveNext
    r = r + 1
Loop
rs.Close
Next i
End Sub
Rechercher des sujets similaires à "requetes sql dynamiques parametres"