› Excel e gli applicativi Microsoft Office › Aprire due recordset in Excel di tabelle access
-
AutoreArticoli
-
Con il codice sottostante prelevo dati da access per fare un registro per la Dogana.
Devo lavorare con due tabelle contemporaneamente, il primo recordset lo crea correttamente, al momento do creare il secondo da lerrore -2147217904 Nessun valore specificato per alcuni parametri necessari. Ho indicato il punto nel codice.
Non riesco a capire dove sbaglio. Office 2016
`Option Explicit Dim StringaDiConnessione Dim OggettoConnessione As Object, OggettoRecordset As Object, OggettoRecordset2 As Object Dim NomeDB As String Dim strSQL As String Dim strNome As String Dim strDescr As String Dim Cella As String, F As String Dim R As Integer Dim Uriga As Long Dim UrigaMesi As Long Dim Urecord As Integer Dim Numero As Integer Dim Data As Date Dim myCell As Range Private Sub CommandButton1_Click() On Error GoTo Err_CommandButton1_Click Const NomeDB As String = "\\DC2\Utenti\Scambio\RegistriDiMagazzino.accdb" 'StringaDiConnessione = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & NomeDB & ";'" StringaDiConnessione = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & NomeDB & ";Persist Security Info=False;" Set OggettoConnessione = CreateObject("ADODB.Connection") OggettoConnessione.Open StringaDiConnessione Set OggettoRecordset = CreateObject("ADODB.Recordset") strSQL = "SELECT * FROM RegistroAutomonitoraggio where (RaData Between %1 And %2) order by RaData" strSQL = Replace(strSQL, "%1", "#" & TextBox1.Value & "#") strSQL = Replace(strSQL, "%2", "#" & TextBox2.Value & "#") Set OggettoRecordset = OggettoConnessione.Execute(strSQL) OggettoRecordset.MoveFirst Application.ScreenUpdating = False R = 4 Do Until OggettoRecordset.EOF Range("A" & R) = OggettoRecordset("RaData") Range("B" & R) = OggettoRecordset("RaRegime") strDescr = OggettoRecordset("RaMrn") & vbNewLine & Space(45) & OggettoRecordset("RaMrnPrec") Range("C" & R) = strDescr Range("D" & R) = OggettoRecordset("RaDazio") Range("E" & R) = Range("E" & (R - 1)) + Range("D" & R) Range("F" & R) = OggettoRecordset("RaIva") Range("G" & R) = Range("G" & Format$(R - 1)) + Range("F" & R) OggettoRecordset.MoveNext R = R + 1 Loop OggettoRecordset.Close Range("C" & R) = "Saldi al " & TextBox2.Value Range("E" & R) = Range("E" & (R - 1)) Range("G" & R) = Range("G" & (R - 1)) R = R + 1 strSQL = "SELECT * FROM LottiChiusi where LoData = %2 order by LoChLotto" strSQL = Replace(strSQL, "%2", "#" & TextBox2.Value & "#") Set OggettoRecordset = OggettoConnessione.Execute(strSQL) OggettoRecordset.MoveFirst Set OggettoRecordset2 = CreateObject("ADODB.Recordset") Do Until OggettoRecordset.EOF strSQL = "SELECT * FROM SaldiLotti where SaLotto = " & OggettoRecordset("LoChLotto") Da Errore -2147217904 Nessun valore per alcuni parametri necessari al momento di creare OggettoRecordset2 Set OggettoRecordset2 = OggettoConnessione.Execute(strSQL) OggettoRecordset2.MoveFirst Range("C" & R) = OggettoRecordset("LoMrn") Range("D" & R) = OggettoRecordset2("SaDazio") Range("E" & R) = Range("E" & (R - 1)) + Range("D" & R) Range("F" & R) = OggettoRecordset2("SaIva") Range("G" & R) = Range("G" & (R - 1)) + Range("F" & R) OggettoRecordset2.Close OggettoRecordset.MoveNext R = R + 1 Loop OggettoRecordset.Close Set OggettoRecordset = Nothing Set OggettoRecordset2 = Nothing Unload Me Range("H2").Select Application.ScreenUpdating = True Exit_CommandButton1_Click: Exit Sub Err_CommandButton1_Click: If Err = 3021 Then MsgBox "Nessun record soddisfa i parametri immessi" Resume Exit_CommandButton1_Click End If MsgBox Err.Number & " " & Err.Description End Sub`Ciao,
non uso più connessioni ADODB da molti anni quindi vado ad intuito più che a memoria.
A parte che trovo inutile
Set OggettoRecordset = CreateObject("ADODB.Recordset")
quando poche righe dopo scriviSet OggettoRecordset = OggettoConnessione.Execute(strSQL)idem per
Set OggettoRecordset2 = CreateObject("ADODB.Recordset")eSet OggettoRecordset2 = OggettoConnessione.Execute(strSQL)comunque io creerei due isatnze distinte anche per la connessione:
Dim OggettoConnessione As Object, OggettoConnessione2 As ObjectProbabilmente sarebbe piu' corretto un Set OggettoRecordset = OggettoConnessione.Open(strSQL) invece che un .Execute
L'errore esce quasi sicuramente perche' il recordset OggettoRecordset e' vuoto (sempre testare .EOF prima delle assegnazioni), quindi OggettoRecordset("LoChLotto") fallisce.
Potrebbe essere vuoto perche' Textbox2 non risulta valorizzato oppure non contiene una data oppure la data non restituisce un sottoinsieme di record.
Fai il debug partendo da
strSQL = "SELECT * FROM LottiChiusi where LoData = %2 order by LoChLotto"e prosegui passo passo controllando tutte le variabili in gioco. Concettualmente quello che vedo mi sembra tutto corretto.A parte che trovo inutile
Set OggettoRecordset = CreateObject("ADODB.Recordset")
quando poche righe dopo scriviSet OggettoRecordset = OggettoConnessione.Execute(strSQL)Probabilmente e' invece corretto perche' lui dichiara la variabile come Object, quindi late binding, e non come oggetto ADO perche' non ha referenziato la libreria (come faccio anche io, del resto).
Grazie a tutti, provati tutti i suggerimenti ma niente da fare. Sembra che non gestisca due Recordset in contemporanea.
Ho risolto creando una tabella d'appoggio con i dati che mi servivano delle due tabelle.
Probabilmente e' invece corretto perche' lui dichiara la variabile come Object, quindi late binding, e non come oggetto ADO perche' non ha referenziato la libreria (come faccio anche io, del resto).
Non pensavo a quello ma mi riferivo al fatto che non serva visto che vale l'ultimo Set. Prendiamo questo esempio dove dichiaro
Dim oMatches as ObjectpoiSet oMatches = CreateObject("Scripting.Dictionary")infineSet oMatches = oRE.Execute(sTextUt)Sub test() Dim oRE As Object, oMatches As Object, oMatch As Object, oSubM As Variant Dim sPatt As String, sTextUt As String Set oRE = CreateObject("vbscript.regexp") Set oMatches = CreateObject("Scripting.Dictionary") sPatt = "(\d+)[a-zA-Z]+(\d+)" sTextUt = "alfa123beta456" With oRE .Global = True .IgnoreCase = True .Pattern = sPatt If .test(sTextUt) Then Set oMatches = oRE.Execute(sTextUt) For Each oMatch In oMatches For Each oSubM In oMatch.submatches Debug.Print oSubM Next oSubM Next oMatch End If End With Set oRE = Nothing Set oMatches = Nothing End Subcome potrai verificare l'oggetto
oMatchessaràObject/MatchCollection2e nonObject/Dictionary.Sembra che non gestisca due Recordset in contemporanea.
Questo non mi sembra possibile. I recordset sono oggetti separati in memoria. Sarebbe come dire che un programma non gestisce due Shapes o due Range.
Capirai che e' piuttosto complicato senza lo scenario particolare sotto mano. Posso provare a costruire un test sulla base di quello che ricavo dallo spezzone Excel ma mi ci vuole un po' di tempo.
come potrai verificare l'oggetto
oMatchessaràObject/MatchCollection2e nonObject/Dictionary.Come fosse un Variant quindi? Ho scoperto una cosa nuova. Di solito assegno fin dall'inizio valori congruenti al tipo di oggetto anche quando dichiaro as Object. Non avrei mai verificato questo comportamento in realta'.
provati tutti i suggerimenti ma niente da fare
Hai provato a eseguire il debug passo passo? Che risultati hai?
E aggiungo: modifica
Set OggettoRecordset = OggettoConnessione.Execute(strSQL)conSet OggettoRecordset = OggettoConnessione.Open(strSQL)Come fosse un Variant quindi?
Esatto, il controllo di coerenza è uno dei "contro" del late binding e dei "pro" dell'early binding.
Ho tutte la variabili congrue. L'istruzione SQL e' corretta ma al momento di eseguire l'istruzione
Set OggettoRecordset2 = OggettoConnessione.Execute(strSQL)Da' l'errore.
E aggiungo: modifica
Set OggettoRecordset = OggettoConnessione.Execute(strSQL)conSet OggettoRecordset = OggettoConnessione.Open(strSQL)Non ho provato, ma se cosi' fosse dovrebbe dare errore sempre, non solo con OggettoRecordset2
Puoi condividere il db Access (ripulito ridotto a pochi record per tabella)?
Eccolo
ma se cosi' fosse dovrebbe dare errore sempre
Non e' detto, con Execute di solito io eseguo un comando (INSERT, UPDATE) mentre Open mi restituisce un recordset (SELECT, TRANSFORM).
Giusto!!! Essendo un campo testo deve essere racchiuso tra apici.
Come al solito mi perdo nelle bischerate.
Grazie scossa
Non e' detto, con Execute di solito io eseguo un comando (INSERT, UPDATE) mentre Open mi restituisce un recordset (SELECT, TRANSFORM)
a mia memoria Open lo usavo per aprire una connessione al db ed Execute per eseguire uno o più comandi (Query) ... ma, ripeto, sono anni che non ci metto mani, né in VBA né in ASP.
-
AutoreArticoli
