Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2021 Créer une requête SQL pour lire plusieurs Ranges?

p'tit vieux

XLDnaute Occasionnel
Bonjour à tous
j'essaie de créer une requête SQL pour lire des Ranges (2 voire plus -Soyons fous ) pour avoir un résultat en colonneS correspondant.
Voici mon code avec plusieurs essais de requêtes. J'y ai mis des commentaires au dessus de chacune d'elle.
Bien sûr il y a toujours la solution de faire une requête sur chaque Range et de créer le tableau compilant les résultats mais pourquoi faire simple
Si quelqu'un a une ou des idées par avance merci à vous

VB:
Sub Test1()
Dim Fichier, ConnectString
Dim Query_str
Dim arr, arr2
Dim RsTLigne, RsTCol

'===== Early Binding !! =========
Dim ADOConn As ADODB.Connection
Dim AdoComand As ADODB.Command
Dim RsT As ADODB.Recordset

  Set ADOConn = New ADODB.Connection
  Set RsT = New ADODB.Recordset
  Set AdoComand = New ADODB.Command
 
  Fichier = ActiveWorkbook.FullName
 
  ConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Fichier & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1;"""
  
  ADOConn.Open ConnectString

'' => OK MAIS:
'' Le 1er RANGE du SELECT DOIT INCLURE la zone du RANGE du 2éme SELECT (celui du IN): Ici [Feuil1$A2:B11] et [Feuil1$B2:B11]
'' Close WHERE ET IN à créer complexe si plus de 2 Ranges. Pas testé avec plus de 2 Ranges
  Query_str = "Select * from [Feuil1$A2:B11] where [F2] in (select [F1] from [Feuil1$B2:B11])"

'' => Resultat exact MAIS:
'' PROBLEME j'ai un tableau 1D des 2 Ranges au lieu d'un tableau 2D
'  Query_str = "Select * from [Feuil1$B2:B11] union all Select * from [Feuil1$A2:A11]"

'' => NON! Pas d'erreur mais résultat UNION
'  Query_str = "Select * from [B2:B92],[A2:A92]"

'' => IDEM CI-DESSUS malgré le nom du classeur.
'  Query_str = "Select * from [Feuil1$B2:B11],[Feuil1$A2:A11]"

'' => IDEM CI-DESSUS avec champs nommées F1 plus nom sur 2 classeurs
'  Query_str = "Select [Feuil1$B2:B11.F1], [Feuil2$A2:A11.F1] from [Feuil1$B2:B11],[Feuil2$A2:A11]"

'' => NON! ERREUR!
'  Query_str = "Select [F1],[F2] from [Feuil1$B2:B11],[Feuil1$A2:A11]"

  RsT.Open Query_str, ADOConn, adOpenStatic

' Affichage
  Range("Q2").CopyFromRecordset RsT
 
' Fermeture
  If RsT.State = adStateOpen Then
    RsT.Close
  End If
  Set RsT = Nothing
  If ADOConn.State = adStateOpen Then
    ADOConn.Close
  End If
  Set ADOConn = Nothing

End Sub
 
Dernière édition:

p'tit vieux

XLDnaute Occasionnel
Oui il peut y avoir une quantité certaine. Je ne la contrôle pas.

Juste pour le "fun" voici un comparatif de ce que fait/faisait mon appli tu comprendras mieux.
Je dis "faisait" car j'ai ajouté tut ce qui est datas externes.
Je suis aussi en train d'écrire/intégrer d'autres fonctionnalités (Récursivité, comparaison type "Between, <= , >= etc. )
 

Pièces jointes

  • COMPARE FINDX.pdf
    903.9 KB · Affichages: 2
Dernière édition:

Dranreb

XLDnaute Barbatruc
Je ne vois aucun rapport entre votre image et la demande.
Le résultat que j'envisageai de produire comportait :
1) — Une référence du classeur et de la feuille source, devant obligatoirement comporter une plage sous forme de tableau.
2) — Sous forme de tableau, une liste des intitulés et des valeurs retenues.
3) — Sous forme de tableau, les colonnes n'ayant pas fait l'objet d'un choix avec les valeurs trouvées dans toutes les lignes.
Mes modules de services sont à considérer comme faisant partie de fournitures privées dont il n'y a pas lieu de chercher comment il fonctionnent pour savoir comment il convient de s'en servir dans la programmation que je qualifie par opposition de "applicative".
J'envisageais d'installer un module standard de service MSujetCBx pour l'élaboration de listes classées et sans doublon destinées à des ComboBox, un module de classe ComboBoxLiées qui combine la gestion de plusieurs ComboBox, un module de classe ComboBoxMmbr à usage interne comme support des ComboBox membres de l'ensemble des ComboBox prises en charge.
Il s'y ajouterais un UserForm utilisant tout ça, qu'il resterait à développer …
 
Dernière édition:

p'tit vieux

XLDnaute Occasionnel
Le rapport?
Dans mon appli je collecte:
1) ce que est recherché,
2) où le chercher
3) ce que l'utilisateur veut obtenir comme résultat
Enfin affichage des résultats

Je cherche à optimiser certaines collectes et traitements (avant et après collectes) de datas de mon appli (question de vitesse)

Donc la requête SQL est juste une idée pour savoir/tester si cela irait plus vite que ce que je fais maintenant dans ma nouvelle (béta) version.
 

dysorthographie

XLDnaute Accro
VB:
Option Explicit

Sub Test1()
Dim Fichier, ConnectString
  Fichier = ActiveWorkbook.FullName
  ConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Fichier & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1;"""
    With CreateObject("Adodb.connection")
    .Open ConnectString
     Range("I2").CopyFromRecordset .Execute(SqlForTo(10, 25)) 'Imagine que j'ai 2 ranges du genre: Range("A10:A25") et Range("C10:C25")
     .Close
  End With
End Sub


Function SqlForTo(Debut As Integer, Fin As Integer) As String
SqlForTo = "Select [Jour],[T° _moyenne/jour] from(" & _
"Select top " & (Fin - Debut + IIf(Debut <10, 2, 1)) & " * " & _
"from(" & vbCrLf & _
"       Select top " & (Fin - 1) & " [Date],[Jour],[T° _moyenne/jour] from [Feuil1$] " & vbCrLf & _
")order by [Date] desc)" & vbCrLf & _
"order by [Date] "
End Function
 
Dernière édition:

p'tit vieux

XLDnaute Occasionnel
Re @dysorthographie
Waouh! Bravo! Je te nomme "REQUETEUR SQL EN CHEF"
Le temps des vacances


Ca marche … Mais !! (Oui je sais encore un mais. Désolé SNIF!)
Il reste quelques trucs que moi pas compris.
Lorsque je remplace les valeurs 10,25 par 2, 400 ...
1) Execute(SqlForTo(2, 400)) j'ai:
Select [Jour],[T° _moyenne/jour] from(Select top 400 * from(
Select top 399 [Date],[Jour],[T° _moyenne/jour] from [Feuil1$]
)order by [Date] desc)
order by [Date]

A cause du (Fin - 1). Pourquoi le -1?

2) L'affichage du résultat est mauvais dans l'exemple il commence à s'afficher à la ligne 36.
Pas compris pourquoi la ligne 36. Mystère.

3) Imaginons que je n'ai pas les entêtes:
par quoi puis-je remplacer [Date], [Jour] etc.
Par [Feuil1$B2:B400], [Feuil1$A2:A400] etc. ??

Je viens tester en remplaçant HDR= No et [Date] etc. par [Feuil1$B2:B400] etc.
J'ai l'erreur suivante:
-2147217904 Microsoft Access Database Engine Aucune valeur donnée pour un ou plusieurs des paramètres requis. 0
Quid si pas d'entête?
Ce qui le cas à 99%.
 
Dernière édition:

dysorthographie

XLDnaute Accro
VB:
Option Explicit

Sub Test1()
Dim Fichier, ConnectString
  Fichier = ActiveWorkbook.FullName
  ConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Fichier & ";Extended Properties=""Excel 12.0;HDR=no;IMEX=1;"""
    With CreateObject("Adodb.connection")
    .Open ConnectString
     Range("I2").CopyFromRecordset .Execute("select [F1],[F3] from [Feuil1$A10:C25]")
     .Close
  End With
End Sub
 

p'tit vieux

XLDnaute Occasionnel

mais en utilisant ta function SqlForTo [F n] ça ne marche plus.

Bon je vais encore réfléchir à ça demain.
Merci pour ton aide

Bonne soirée à tous
 

dysorthographie

XLDnaute Accro
VB:
Option Explicit

Sub Test1()
Dim Fichier, ConnectString
  Fichier = ActiveWorkbook.FullName
  ConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Fichier & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1;"""
    With CreateObject("Adodb.connection")
    .Open ConnectString
     Range("I2").CopyFromRecordset .Execute(SqlForTo(10, 25)) 'Imagine que j'ai 2 ranges du genre: Range("A10:A25") et Range("C10:C25")
     .Close
  End With
End Sub


Function SqlForTo(Debut As Integer, Fin As Integer) As String
SqlForTo = "Select [F1],[F3] from(" & _
"Select top " & (Fin - Debut + 1) & " * " & _
"from(" & vbCrLf & _
"       Select top " & Fin  & " * from [Feuil1$] " & vbCrLf & _
")order by [F2] desc)" & vbCrLf & _
"order by [F2] "
End Function
 
Dernière édition:

dysorthographie

XLDnaute Accro
VB:
Option Explicit

Sub Test1()
Dim Fichier, ConnectString
  Fichier = ActiveWorkbook.FullName
  ConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Fichier & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1;"""
    With CreateObject("Adodb.connection")
    .Open ConnectString
     Range("I2").CopyFromRecordset .Execute(SqlForTo(100, 110)) 'Imagine que j'ai 2 ranges du genre: Range("A10:A25") et Range("C10:C25")
     .Close
  End With
End Sub


Function SqlForTo(Debut As Integer, Fin As Integer) As String
Dim nb As Integer
nb = Fin - Debut + 2
SqlForTo = "Select [F1],[F3] from(" & _
"Select top " & (nb - 1) & " * " & _
"from(" & vbCrLf & _
"       Select top " & (Fin - 1) & " * from [Feuil1$]  where [F2]<>'Date'" & vbCrLf & _
")order by format([F2],'yyyy-mm-dd') desc)" & vbCrLf & _
"order by format([F2],'yyyy-mm-dd')  "
End Function
 

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…