Scrittura su sqlserver



  • Scrittura su sqlserver
    di biss73 (utente non iscritto) data: 09/01/2015 14:08:07

    Salve tutti,
    ho di nuovo bisogno del vostro grandissimo aiuto
    vi spiego brevemente:
    su un foglio Excel ho tre colonne A,B,C con dei dati che dovrei andare a scrivere su un registro di SQL server 2008, in rete ho trovato un codice che lo fa e fin qui tutto OK.
    Problema
    il database non accetta la scrittura di un di più record e quindi devo inserirli uno alla volta, anche se sul foglio di lavoro ho le tre colonne A,B,C piene fino alla riga 300 mi scrive solo la riga 1 ( A1,B1,C1 ).
    vorrei far eseguire un ciclo alla macro che ho trovato per fare in modo che mi scorra riga per riga fin quando ci sono le celle piene ( es. riga 320 o più ) ma non riesco a procedere sono sicuro che si possa fare ma sinceramente non sono in grado. posto il codice che sto utilizzando, anche se questo legge il range di celle delle colonne A,B,C
    Ringrazio anticipatamente
    Saluti
     
    Public Sub Scrivi_Dati()
    
    On Error GoTo RigaErrore
    
        Dim cn As Object
        Dim sh As Worksheet
        Dim sSQL As String
        Set cn = CreateObject("ADODB.Connection")
        Set sh = Worksheets("Foglio2")
        
        
        
        With sh
            sSQL = "INSERT INTO Ubicazio " & _
                "(ID, Codice, Descrizione) " & _
                " VALUES (" & _
                "'" & .Range("A1").Value & "', " & _
                "'" & .Range("B1").Value & "', " & _
                "'" & .Range("C1").Value & "'" & _
                ")"
        End With
        
        With cn
            .CursorLocation = 1
            .Open "Provider=SQLNCLI10;" & _
                "Server=UTENTE-PCSQLEXPRESS;" & _
                "Database=mig50;" & _
                "Trusted_Connection=yes;"
            .Execute sSQL, , 1
        End With
        
    RigaChiusura:
        If cn.State = 1 Then
            cn.Close
        End If
    
        Set cn = Nothing
        Set sh = Nothing
        Exit Sub
    
    RigaErrore:
        MsgBox Err.Number & vbNewLine & Err.Description
        Resume RigaChiusura
    
    End Sub
    
    
    



  • di Vecchio Frac data: 09/01/2015 15:24:24

    Infatti tu dici via codice di eseguire la scrittura solo di A1, B1 e C1.
    Leggi bene: tu imposti sSQL in modo che successivamente l'oggetto "cn" esegua l'INSERT INTO di quei soli tre VALUES.
    Devi scorrere il range di celle e eseguire ogni volta l'istruzione di scrittura (INSERT INTO):
    - for each per scorrere il range
    - if per vedere se hai raggiunto una riga vuota
    - costruzione in modo adeguato di sSQL
    - Execute in modo appropriato dell'istruzione SQL
    - next






  • di Biss73 (utente non iscritto) data: 09/01/2015 15:36:31

    Ciao e grazie per aver risposto in modo così immediato,
    Ti chiedo se gentilmente poi modificare il codice postato da me ( se non chiedo troppo ) onde evitare ancora errori visto che non sono molto esperto in programmazione.
    Grazie



  • di Vecchio Frac data: 09/01/2015 15:59:01

    A occhio e croce una cosa così.
    Salta la riga 1 perchè probabilmente lì ci sono le intestazioni di colonna.
    Non testato ovviamente, mi mancano i dati e il provider.
     
    Option Explicit
    
    Public Sub Scrivi_Dati()
    Dim cn As Object
    Dim cell As Range
    Dim sSQL As String
    
        Set cn = CreateObject("ADODB.Connection")
        
        With cn
            .CursorLocation = 1
            .Open "Provider=SQLNCLI10; Server=UTENTE-PCSQLEXPRESS; Database=mig50; Trusted_Connection=yes;"
        End With
        
        Worksheets("Foglio2").Activate
        
        On Error GoTo RigaErrore
        
        For Each cell In Range("A:A")
            If cell.Row > 1 Then
                If Trim(cell) = "" Then Exit For
    
                sSQL = "INSERT INTO Ubicazio (ID, Codice, Descrizione) " & _
                        " VALUES ('" & cell & "', '" & cell.Offset(, 1) & "', '" & cell.Offset(, 2) & "')"
                cn.Execute sSQL, , 1
            End If
        Next
        
    RigaChiusura:
        If cn.State = 1 Then cn.Close
        Set cn = Nothing
        Exit Sub
    
    RigaErrore:
        MsgBox Err.Number & vbNewLine & Err.Description
        Resume RigaChiusura
    
    End Sub






  • di biss73 (utente non iscritto) data: 09/01/2015 17:25:48

    Ciao, Grazie 1000 Vecchio frac funziona alla grande gentilissimo e disponibile come sempre,
    approfitto per chiederti ancora una piccola informazione ( spero non me ne voglia):
    Visto che devo scrivere altri record su altri registri con campi in più dell'SQL dovrei :
    1- cambiare il nome del registro da ( Ubicazio , a pippo ),
    2- aggiungere a (ID, Codice, Descrizione) devo aggiungere i nuovi campi es (ID, Codice, Descrizione, Articolo , Ecc.) o devo cambiare altro??
    Ti chiedo: c'è un modo di scrivere un codice dinamico che comprenda più campi invece di 3 tenendo conto che sul file di Excel ogni campo mi prende una colonna ?
    Ti ringrazio ancora
    Saluti.




  • di Vecchio Frac data: 09/01/2015 18:24:02

    Appena posso rispondo meglio ma intanto cerca con Google: "ADO Query parametriche"





  • di biss73 (utente non iscritto) data: 09/01/2015 18:36:30

    Grazie mille
    Saluti



  • di Vecchio Frac data: 09/01/2015 18:45:17

    1. Se il database è lo stesso ma è composto da più tabelle, la stringa di connessione al provider non cambia (quindi non devi modificare "cn"); quello che tu chiami "registro" io lo chiamo "tabella" ma il concetto è uguale
    2. i nuovi campi si possono aggiungere semplicemente con la sintassi che hai visto per INSERT INTO creano una nuova "sSQL" che contiene la nuova istruzione.

    Il file di Excel è come un database: ogni range di dati contiguo in Excel è gestibile come una tabella (registro?) di SQL, ogni colonna di Excel è un campo di SQL, ogni riga di Excel è un record di SQL.
    Puoi anche non conoscere a priori il numero di campi di Excel, nè come si chiamano, e anche quelli del database sql server di destinazione, ma dovrebbero almeno avere lo stesso numero di campi:
    - per ogni riga di Excel:
    - la colonna 1 di Excel viene assegnata al Field(0) del db sql server;
    - la colonna 2 di Excel viene assegnata al Field(1) del db sql server;
    - la colonna n di Excel viene assegnata al Field(n) del db sql server; ecc.

    Con le query parametriche (che conosco bene con SQL Jet di Access, meno bene con ADODB ma non dovrebbe esserci differenza abissale) puoi semplificare l'inserimento dei dati e renderli anche più sicuri (evitando la famosa SQL injection dei dati, fonte di guai soprattutto con gli apici semplici).





  • di Vecchio Frac data: 09/01/2015 18:50:16

    Ti suggerisco questa lettura, di un utilizzatore di VB6 che ho apprezzato quando frequentavo VBT&T anni fa:
    h t t p://nuke.vbcorner.net/Articoli/VB60/ADOParametrieaffini/tabid/85/Default.aspx





  • di Biss73 (utente non iscritto) data: 09/01/2015 19:26:53

    Ti ringrazio molto per il consiglio
    Ti auguro un buon week
    Saluti



  • di biss73 (utente non iscritto) data: 10/01/2015 17:26:38

    Ciao, ho seguito il tuo consiglio vecchio frac, ma purtroppo le mie conoscenze in fatto di programmazione sono limitate
    di conseguenza sono di nuovo a chiedere aiuto.
    devo scrivere su una tabella diversa sempre sull' SQL composta da 17 record ho modificato il tuo codice aggiungendo i campi di INSERT e VALUES pensavo che bastasse
    ma mi sbagliavo
    mi da errore:

    -2147217900
    Il numero delle colonne dell' istruzione INSERT è maggiore del numero dei valori specificati nella clausola VALUES. Il numero dei valori della clausola deve corrispondere al numero delle colonne specificate nell' istruzione

    Non so dove sbaglio ho fatto più prove ma senza risultato posto il codice modificato da me
    ti ringrazio anticipatamente
    saluti

     
    Option Explicit
    
    Public Sub Scrivi_Struttura()
    Dim cn As Object
    Dim cell As Range
    Dim sSQL As String
    
        Set cn = CreateObject("ADODB.Connection")
        
        With cn
            .CursorLocation = 1
            .Open "Provider=SQLNCLI10; Server=UTENTE-PCSQLEXPRESS; Database=mig50; Trusted_Connection=yes;"
        End With
        
        Worksheets("Foglio8").Activate
        
        On Error GoTo RigaErrore
        
        For Each cell In Range("A:A")
            If cell.Row > 1 Then
                If Trim(cell) = "" Then Exit For
    
                sSQL = "INSERT INTO Struttur (ID, Livello, Padre, F_tag, F_ScTcn, IdCentriCo, IdUbicazio, idTipStrut, Codice, Descrizione, Qta, Nota, Pathid, F_templPre, F_Figlio, PathIdEsterno, F_Comp) " & _
                        " VALUES ('" & cell & "', '" & cell.Offset(, 1) & "', '" & cell.Offset(, 2) & cell.Offset(, 3) & cell.Offset(, 4) & cell.Offset(, 5) & cell.Offset(, 6) & cell.Offset(, 7) & cell.Offset(, 8) & cell.Offset(, 9) & cell.Offset(, 10) & cell.Offset(, 11) & cell.Offset(, 12) & cell.Offset(, 13) & cell.Offset(, 14) & cell.Offset(, 15) & cell.Offset(, 16) & cell.Offset(, 17) & "')"
                cn.Execute sSQL, , 1
            End If
        Next
        
    RigaChiusura:
        If cn.State = 1 Then cn.Close
        Set cn = Nothing
        Exit Sub
    
    RigaErrore:
        MsgBox Err.Number & vbNewLine & Err.Description
        Resume RigaChiusura
    
    End Sub
    
    
    
    
    
    



  • di Vecchio Frac data: 10/01/2015 17:53:03

    Bè, il messaggio di errore è chiarissimo: i campi sono 17, e 17 devono essere i valori che inserisci nei campi con VALUES.
    Ho contato... e sono 18 ^_^
    ID è valorizzato da cell
    Livello è valorizzato da cell.Offset(,1)
    Padre è valorizzato da cell.Offset(,2)
    eccetera, finchè scopri che l'ultimo campo F_Comp è valorizzato da cell.Offset(,16) (giustamente: se cell è il primo, il diciassettesimo è individuato da sedici celle successive). Peccato che nella sfilza di VALUES compaia anche un cell.Offset(,17) che invece devi togliere altrimenti i conti non tornano (ecco il consiglio sulle query parametriche).
    Se invece tutti quei cell.Offset puntano a un dato da inserire nel db, i campi devono essere 18 (e allora ne manca uno in INSERT INTO).
    Fai due conti e vedrai che lo capisci subito :)





  • di Vecchio Frac data: 10/01/2015 17:56:38

    Ah c'è anche un altro errore: gli apici.
    Devi mettere apici prima e dopo ogni cell.Offset altrimenti costruisci un'unica lunga stringa che viene messa al posto di UN campo.
    Per questo ulteriore motivo ti riconsiglio le query parametriche :)

     
    sSQL = "INSERT INTO Struttur (ID, Livello, Padre, F_tag, F_ScTcn, IdCentriCo, IdUbicazio, idTipStrut, Codice, Descrizione, Qta, Nota, Pathid, F_templPre, F_Figlio, PathIdEsterno, F_Comp) " & _
                        " VALUES ('" & cell & "', '" & cell.Offset(, 1) & "', '" & cell.Offset(, 2) & "', '" & cell.Offset(, 3) & "', '" & cell.Offset(, 4) & "', '" & cell.Offset(, 5) & "', '" & cell.Offset(, 6) & "', '" & cell.Offset(, 7) & "', '" & cell.Offset(, 8) & "', '" & cell.Offset(, 9) & "', '" & cell.Offset(, 10) & "', '" & cell.Offset(, 11) & "', '" & cell.Offset(, 12) & "', '" & cell.Offset(, 13) & "', '" & cell.Offset(, 14) & "', '" & cell.Offset(, 15) & "', '" & cell.Offset(, 16) & "', '" & cell.Offset(, 17) & "')"






  • di biss73 (utente non iscritto) data: 10/01/2015 18:28:57

    Ciao, grazie per la risposta non ci speravo visto che e sabato
    subito dopo postato il mio codice ho ricontrollato e ho notato anche io l'errore e ho risolto
    volevo dirtelo ma vedo che lo hai trovato anche tu il problema ( non avevo dubbi in merito)
    grazie ancora Vecchio Frac
    gentilissimo e tempestivo come sempre
    saluti e buon weeck
    ciao



  • di biss73 (utente non iscritto) data: 10/01/2015 18:34:59

    Ops scusami di nuovo una sola ultima piccolissima cosa da chiedere:
    se vado ad scrivere una riga sul data base se questa gia è presente non mi scrive nemmeno le successive
    almeno che non vada prima a cancellarle ( dentro il Programma del data base) a mano.

    c'e' una funzione che prima di scrivere cancelli i records inseriti precedentemente??
    Grazie



  • di Vecchio Frac data: 10/01/2015 22:31:01

    Mancano informazioni.
    "Se questa è già presente non mi scrive nemmeno le successive": si blocca con un errore? se sì, quale? o non ottieni alcun errore? non si ferma ma non scrive dati? devi prima cancellare i record esistenti: questo mi fa pensare che l'ID non viene aggiornato e poichè è probabilmente na chiave primaria, non puoi avere duplicati.
    Questa istruzione: "INSERT INTO Struttur (ID, ...) VALUES (cell, ..." inserisce il valore di cell nel campo dedicato all'ID, ma chiaramente cell deve essere di volta diverso.

    In realtà non deve esserci "... una funzione che prima di scrivere cancelli i records inseriti precedentemente", sarebbe stupido inserire record e doverli subito cancellare per far posto a quelli successivi... che database sarebbe? :)





  • di Biss73 (utente non iscritto) data: 11/01/2015 00:39:34

    Ciao, scusa l'ora
    Infatti non accetta duplicati di e si blocca nello scrivere anche il resto purtroppo
    Il messaggio di errore è quello che ho descritto prima
    -21 ecc ecc ( come ti ripeto non sono un grande esperto in programmazione )
    Non so se esista una funzione che possa modificare i records già inseriti
    Mi dice che è impossibile inserire perché il primo dato già esiste nel data base e non accetta duplicati
    Potresti gentilmente darmi una dritta??
    Grazie ancora e scusa l'ora
    Saluti



  • di Vecchio Frac data: 11/01/2015 09:10:21

    L'istruzione sql che modifica dati già inseriti è UPDATE.
    Bisognerebbe vedere lo schema della tua tabella per capire quali sono i dati non duplicabili e poi analizzare una o due righe di dati Excel che cerchi di dare in pasto al db.
    Se riesci ad aprire il db con Access, guarda quali sono i campi con chiave e nel file di Excel cerca di avere questi campi con valori univoci.





  • di Biss73 (utente non iscritto) data: 11/01/2015 11:02:45

    Giorno
    Grazie ancora per il magnifico supporto che mi stai dando
    Purtroppo tutti i campi del db anno una chiave ( che non può essere duplicata )
    Io cerco di aggiornare solo i dati ma se non riesco mi andrebbe anche bene cancellare tutto e poi riscrivere i nuovi dati ( anche se non è la soluzione più bella) l'importante che risolva se credi ti possa essere di aiuto posso mandarti uno o più screen del db
    Grazie ancora
    Saluti



  • di biss73 (utente non iscritto) data: 11/01/2015 12:08:36

    Ciao, scusa se anche oggi che è domenica ti disturbo se hai la possibilità di darci un occhio ti allego dei screen del db e il file Excel con un foglio delle note per descrivere il problema.
    Nb ovviamente i dati del foglio non sono quelli reali ma la struttura è quella che vedi
    grazie ancora
    saluti



  • di Vecchio Frac data: 11/01/2015 14:55:08

    Hai fatto bene ad allegare qualcosa, ma dalle immagini non riscontro la struttura del db che stai usando (i campi sono diversi), perciò magari noi con INSERT INTO stiamo andando a scrivere delle stringhe (infatti circondiamo le celle con apici prima di inserirci il valore di cell.Offset) quando in realtà il campo di destinazione deve essere numerico e qui si blocca.

    Non ti è chiaro perchè accade che " se il campo ID non è presente funziona alla grande"? bè, ogni volta che fai girare la macro cerchi di INSERIRE nel db tutti i record dall'inizio, compreso quindi l'ID, che se è presente e ha già un valore non può avere lo stesso valore. Ecco perchè se cancelli il campo ID funziona.
    L'istruzione che cancella l'intera tabella dal db è DROP e funziona così:
    cn.Execute "DROP TABLE tabella"
    prima di far girare la macro.
    Solo che di solito non si fa mai... cioè di solito si fa girare una macro che accoda dati esistenti senza distruggere quelli precedenti :) E devi tener conto del campo ID: io ragionerei così:
    - lancio la macro Excel
    - che recupera l'ultimo ID scritto nel database
    - e cerca quindi in Excel la riga che corrisponde all'ID successivo a quello scritto nel db
    - poi legge da quella riga fino alla fine e con INSERT INTO scrive nel db i record (che quindi saranno nuovi9, accodati al db esistente, e non duplicati perchè l'ID sarà univoco)

    Se il ragionamento ti sembra corretto, ed è così che vorresti che andasse, possiamo provare a scrivere un po' di codice... comincia tu ;)






  • di biss73 (utente non iscritto) data: 11/01/2015 15:29:05

    Ciao, gentilissimo come sempre
    effettivamente la tua proposta è ancora più interessante di quella proposta da me ( su questo non ho dubbi)
    il problema è che ( come ti confermo ancora una volta ) non so da che parte cominciare a scrivere un codice che legga l'ultimo id inserito ( non ti vorrei far fare il lavoro a posto mio ma..... )
    ho trovato una macro che mi legge le tabelle e mi riporta il contenuto da questa penso si possa partire per fare quello che mi hai suggerito te, la posto cosi si possono prendere spunti
    grazie ancora per il formidabile aiuto
    Saluti
     
    Public Sub Leggi_struttura()
    
    On Error GoTo RigaErrore
    
        Dim cn As Object
        Dim rs As Object
        Dim sh As Worksheet
        Dim sSQL As String
    
        Set cn = CreateObject("ADODB.Connection")
        Set rs = CreateObject("ADODB.Recordset")
        Set sh = Worksheets("Foglio8")
        
        sSQL = "SELECT * FROM struttur" ' seleziona la tabella da leggere
        
        With cn
            .CursorLocation = 1
            .Open "Provider=SQLNCLI10;" & _
                "Server=UTENTE-PCSQLEXPRESS;" & _
                "Database=mig50;" & _
                "Trusted_Connection=yes;"
        End With
        
        With rs
            .CursorLocation = 1
            .Open sSQL, cn, 1, 3, 1
        End With
        
        With sh
            .Range("A2").Cells.Clear
            .Range("A2").CopyFromRecordset rs
        End With
        
    RigaChiusura:
        If rs.State = 1 Then
            rs.Close
        End If
        
        If cn.State = 1 Then
            cn.Close
        End If
    
        Set rs = Nothing
        Set cn = Nothing
        Set sh = Nothing
        Exit Sub
    
    RigaErrore:
        MsgBox Err.Number & vbNewLine & Err.Description
        Resume RigaChiusura
    
    End Sub
    
    
    
    
    
    
    
    
    
    



  • di Vecchio Frac data: 11/01/2015 16:42:28

    Bè sì, la strada è giusta.
    Certo si può semplificare perchè tanto a te basta recuperare un ID da una connessione esistente, non ti serve riportarlo sul foglio Excel.
    Riprendo in esame il codice che deve scrivere sul database.
    Fai qualche prova, aggiungi qualche riga, avvia la macro, aggiungi qualche riga, avvia la macro.
    Importante è che non ci siano righe vuote, e che gli ID siano consecutivi.
    Spero di non aver fatto errori, è difficile lavorare al buio :)


     
    Option Explicit
    
    Public Sub Scrivi_Struttura()
    Dim cn As Object
    Dim cell As Range
    Dim sSQL As String
    Dim Last_ID as long, Last_cell as range
    
        Set cn = CreateObject("ADODB.Connection")
        
        With cn
            .CursorLocation = 1
            .Open "Provider=SQLNCLI10; Server=UTENTE-PCSQLEXPRESS; Database=mig50; Trusted_Connection=yes;"
        End With
        
        'recuperiamo l'ultimo ID dal database e lo assegniamo a Last_ID
        Last_ID = cn.execute("SELECT Max(ID) FROM struttur")(0)
    
        Worksheets("Foglio8").Activate
        
        set Last_cell = range("A:A").find(Last_ID)    
    
        For Each cell In Range("A" & (Last_cell.row + 1) & ":A65535")
           If Trim(cell) = "" Then Exit For
    
                sSQL = "INSERT INTO Struttur (ID, Livello, Padre, F_tag, F_ScTcn, IdCentriCo, IdUbicazio, idTipStrut, Codice, Descrizione, Qta, Nota, Pathid, F_templPre, F_Figlio, PathIdEsterno, F_Comp) " & _
                        " VALUES ('" & cell & "', '" & cell.Offset(, 1) & "', '" & cell.Offset(, 2) & cell.Offset(, 3) & cell.Offset(, 4) & cell.Offset(, 5) & cell.Offset(, 6) & cell.Offset(, 7) & cell.Offset(, 8) & cell.Offset(, 9) & cell.Offset(, 10) & cell.Offset(, 11) & cell.Offset(, 12) & cell.Offset(, 13) & cell.Offset(, 14) & cell.Offset(, 15) & cell.Offset(, 16) & cell.Offset(, 17) & "')"
                cn.Execute sSQL, , 1
        Next
        
        cn.Close
        Set cn = Nothing
    End Sub






  • di biss73 (utente non iscritto) data: 11/01/2015 17:29:45

    Ciao grazie ancora gentilissimo come sempre ho provato il tuo codice ma mi da errore poi ho corretto la parte di codice che posto ( pensavo che era solo quello il problema ( ti eri scordato qualche "" ) fin li ci ero arrivato
    Lerrore è il seguente:

    -2147217873 (80040e2f)':
    l'istruzione INSERT è in conflitto con il vincolo FOREIGN KEY
    " struttur_FK00", il conflitto si è verificato nella tabella " dbo.CentriCo",
    column 'Id' del database 2Mig50"

    il Mig50 è il mio database
    come dal file che ti ho allegato ( idCentriCo e idUbicazione e IdTipStrut ) non sempre sono colonne che contengono dati ( forse è quello il problema ) almeno credo
    PS. se vuoi e puoi sono disponibile anche a un collegamento con (team Viuwer; ID 818 275 334 ) o altro
    grazie moltissimo
    saluti
     
                sSQL = "INSERT INTO Struttur (ID, Livello, Padre, F_tag, F_ScTcn, IdCentriCo, IdUbicazio, idTipStrut, Codice, Descrizione, Qta, Nota, Pathid, F_templPre, F_Figlio, PathIdEsterno, F_Comp) " & _
                        " VALUES ('" & cell & "', '" & cell.Offset(, 1) & "', '" & cell.Offset(, 2) & "', '" & cell.Offset(, 3) & "', '" & cell.Offset(, 4) & "', '" & cell.Offset(, 5) & "', '" & cell.Offset(, 6) & _
                        "', '" & cell.Offset(, 7) & "', '" & cell.Offset(, 8) & "', '" & cell.Offset(, 9) & "', '" & cell.Offset(, 10) & "', '" & cell.Offset(, 11) & "', '" & cell.Offset(, 12) & "', '" & cell.Offset(, 13) & _
                        "', '" & cell.Offset(, 14) & "', '" & cell.Offset(, 15) & "', '" & cell.Offset(, 16) & "')"
    



  • di Vecchio Frac data: 11/01/2015 20:21:17

    Non conosco così bene Sql Server 2008 da darti una risposta precisa.
    C'è una chiave esterna che non viene valorizzata.
    L'idea di Teamviewer per dare un'occhiata da vicino è buona ma dobbiamo trovare il momento giusto... questione di tempistica :)





  • di Biss73 (utente non iscritto) data: 11/01/2015 20:55:40

    Ciao , scusami ancora una volta, ho fatto ulteriori prove con il codice che mi hai postato su una tabella che contiene solo un Id ( es. id, nome, descrizione ) e funziona benissimo
    Il problema sembra esserci se la tabella contiene più di un Id ( come nel file che ho allegato )
    Per quanto riguarda il team viewer io sono disponibilissimo anche durante l'orario di lavoro ( se vuoi dammi un orario così mi faccio trovare libero )
    Ancora ti ringrazio e scusami per il disturbo
    Saluti



  • di Vecchio Frac data: 12/01/2015 07:12:25

    cit. "Il problema sembra esserci se la tabella contiene più di un Id"
    ---> Al 99% il problema è (come avevo già accennato) che il campo id accetta probabilmente un valore numerico mentre in sSQL noi gli passiamo un valore stringa: tutti i cell.Offset sono circondati da virgolette e vengono inseriti nel db come stringa, e questo è sbagliato se il campo di destinazione è numerico. Devi individuare i campi id e togliere le virgolette prima e dopo cell.Offset da sSQL nei punti opportuni.
    Un argomento in più per utilizzare le query parametriche.





  • di biss73 (utente non iscritto) data: 12/01/2015 09:23:41

    Giorno, grazie di nuovo
    ho fatto alcune prove stamattina in base al tuo suggerimento ma ricevo ancora errore del tipo:

    conversione non riuscita durante la conversione del valore varchar '& cell.Offset(,5)&' nel tipo di dati int

    forse sbaglio ancora qualcosa non saprei
    ho modificato cosi : , ' & cell.Offset(, 5) & ', ma non va ancora
    L' utilizzo delle query parametriche sarebbe risolutivo?
    il problema che non so da dove e come iniziare a scrivere il codice purtroppo
    in attesa di un tuo ( o Atri che vogliano cimentarsi ) aiuto ringrazio ancora per l'ennesima volta
    Saluti



  • di Vecchio Frac data: 12/01/2015 09:42:56

    cit "conversione non riuscita durante la conversione del valore varchar '& cell.Offset(,5)&' nel tipo di dati int "
    ---> Questa è la conferma alla mia ipotesi :) non consente di inserire un valore stringa in un campo che accetta un valore numerico.
    Allora devi costruire la stringa sSQL nel modo giusto.

    cit. "ho modificato cosi : , ' & cell.Offset(, 5) & ', ma non va ancora "
    ---> attento al gioco degli apici racchiusi da doppie virgolette. Se la cella dopo cinque colonne è quella numerica:
    ... ", " & cell.Offset(, 5) & ", " ...

    Ti sto preparando un riassunto per usare query parametriche.
    E sì, sarebbe risolutivo anche se ci vuole un piccolo sforzo iniziale per capire come sono fatte.






  • di Biss73 (utente non iscritto) data: 12/01/2015 10:49:48

    Ciao , ho provato anche a scrivere il codice come hai detto te ma il risultato purtroppo non cambia resto in attesa di una tua soluzione
    Grazie mille
    Saluti



  • di Vecchio Frac data: 12/01/2015 11:08:15

    (sintesi da vbcorner di Giorgio Brausi)

    Tre ragioni a favore degli oggetti ADO Command e Parameter:
    1. non siamo più costretti a peripezie ortografiche, districandoci tra apici, cancelletti, virgole, parentesi aperte e chiuse, raddoppio degli apici per i campi di testo, ecc.
    2. la query è abbastanza semplice da creare, da capire e quindi da manutenere.
    3. la query funzionerà senza alcuna modifica su qualsiasi database la utilizzeremo. Anche se qualche differenza piccola c’è, legata allo specifico dialetto SQL

    1° vantaggio
    Invece di scrivere una stringa come questa:
    INSERT INTO tabella
    (cognome, nome, indirizzo, luogo, datainizio, datafine, tipoevento) VALUES
    ('" & txtCognome.text & "','" & txtNome.Text & "','" & txtIndirizzo
    & "','" & txtLuogo.Text & "'",#" & txtDataInizio.Text & "#,#"
    & txtDataFine.Text & "#,'" & txtTipoEcento.Text & "')"


    dobbiamo semplicemente indicare il valore dei campi, cioè non siamo più costretti a sottostare alla formattazione dei dati.
    Creiamo un oggetto Parameter ed un oggetto Command:
    Dim par As ADODB.Parameter
    Dim cmd As ADODB.Command
    Set cmd = New ADODB.Command


    L’istruzione INSERT INTO dell’esempio precedente, utilizzando però i parametri, diventa:
    Dim sSQL As String
    sSQL = sSQL & " INSERT INTO tabella"
    sSQL = sSQL & " (cognome, nome, indirizzo, luogo, datainizio, datafine, tipoevento)"
    sSQL = sSQL & " VALUES (@cognome, @nome, @indirizzo, @luogo, @datainizio, @datafine, @tipoevento)"


    Abbiamo riscritto i nomi dei campi, preceduti dal simbolo “@”. Si tratta di semplici segnaposto che saranno sostituiti automaticamente dai relativi parametri, che ora ci prepariamo a creare.
    Avremmo anche potuto indicare dei punti interrogativi ma la leggibilità ne viene meno:
    sSQL = sSQL & " VALUES ?, ?, ?, ?, ?, ?, ?)"

    E’ meglio usare un nome descrittivo, in questo modo siamo sicuri che ogni parametro andrà assegnato al segnaposto giusto. Se usassimo il punto interrogativo (“?”) dovremmo stare attenti che la sequenza dei parametri corrisponda esattamente a quella dei campi, ciò che invece può non avvenire utilizzando i segnaposto mnemonici.

    Per la creazione dei parametri usiamo il metodo CreateParameter, la cui sintassi è:
    Set parameter = command.CreateParameter (Name, Type, Direction, Size, Value)

    Assegniamo quindi alla variabile oggetto Par il parametro corrispondente, dichiarata all'inizio del codice (utilizziamo la sintassi con With per riferirci all’oggetto Command e risparmiare digitazione):
    With cmd
    Set par = .CreateParameter ("@cognome", adVarChar, adParamInput, 50, txtCognome.Text)
    .Parameters.Append par
    Set par = .CreateParameter ("@nome", adVarChar, adParamInput, 50, txtNome.Text)
    .Parameters.Append par
    Set par = .CreateParameter ("@indirizzo", adVarChar, adParamInput, 50, txtIndirizzo.Text)
    .Parameters.Append par
    Set par = .CreateParameter ("@luogo", adVarChar, adParamInput, 50, txtLuogo.Text)
    .Parameters.Append par
    Set par = .CreateParameter ("@datainizio", adDate, adParamInput, , txtDataInizio.Text)
    .Parameters.Append par
    Set par = .CreateParameter ("@datafine", adDate, adParamInput, , txtDataFine.Text)
    .Parameters.Append par
    Set par = .CreateParameter ("@tipoevento", adVarChar, adParamInput, 20, txtTipoEvento.Text)
    .Parameters.Append par
    End With


    A prima vista si ha l'impressione che la quantità di codice da scrivere sia maggiore di quella necessaria nel vecchio modo. In realtà, il più delle volte si tratta di fare un semplice copia ed incolla delle stesse righe in cui cambiano solo alcuni dei 4 o 5 parametri richiesti, a favore di una maggior leggibilità e comprensione del codice. La cosa interessante che notiamo è come viene passato il valore (l'ultimo parametro) al metodo CreateParameter. Come si vede nessun cancelletto, virgola, parentesi, o altre formattazioni varie, perché è il parametro stesso che si incarica di fornire il valore nel giusto formato a seconda del tipo di dato.
    A proposito dei tipi di dato… bisogna utilizzare quelli conosciuti dal provider utilizzato. Se non hai impostato il riferimento alla libreria ADO puoi utilizzare il corrispondente valore numerico.
    Per SQL Server vedi il sito: h t t p://www.w3schools.com/asp/ado_datatypes.asp) per il mapping dei tipi di dato disponibili (per esempio adVarChar (200) per le stringhe, adSmallInt (2) per gli interi, adDouble (5) per i double, ecc.).

    Prima di eseguire il Command, dobbiamo dirgli cosa deve fare:
    cmd.ActiveConnection = CN ‘è la connessione aperta al database
    cmd.CommandType = adCmdText ‘adCmdText = 1: è il Tipo di comando, è semplice testo
    cmd.CommandText = sSQL ‘il testo del comando, la nostra query


    Infine possiamo eseguire il Command:
    cmd.Execute






  • di Vecchio Frac data: 12/01/2015 11:09:12

    cit. "ma il risultato purtroppo non cambia"
    ---> mi dispiace, purtroppo stiamo un po' brancolando nel buio. Magari stasera avviamo una sessione con TeamViewer





  • di biss73 (utente non iscritto) data: 12/01/2015 11:17:47

    Ciao, ok aspetto con ansia fammi sapere solo l'orario cosi mi libero da impegni ( moglie & figli)
    Buona giornata



  • di Vecchio Frac data: 12/01/2015 11:54:01

    Per non tediare nessuno con inutili messaggi interlocutori spostiamo la nostra discussione su questa email:
    staff@excelvba.it
    mentre qui posteremo la soluzione finale, nel caso interessi a qualcuno.





  • di biss73 (utente non iscritto) data: 12/01/2015 12:16:13

    Ciao, ok sono d'accordo con te ti ho inviato una mail fammi sapere
    Saluti



  • di biss73 (utente non iscritto) data: 12/01/2015 13:36:32

    Ciao, credo che la casella di posta che mi hai indicato non sia corretta mi da errore



  • di Vecchio Frac data: 12/01/2015 14:36:18

    Ho ricevuto perfettamente la tua mail e ti ho pure risposto ;)





  • di Vecchio Frac data: 16/01/2015 11:03:40

    Riapro la discussione solo per marcarla come risolta.
    Dopo uno scambio con "biss73" abbiamo verificato problemi nell'uso delle query parametriche da me suggerito. Abbiamo risolto con una brutale SQL injection sui campi chiave dopo aver trattato e gestito il caso dei campi nulli: essendoci dei campi chiave esterni vanno valorizzati anche quelli tenendo conto dei valori non duplicabili: ad ogni cella vuota incremento un contatore che poi inserisco via SQL nel corrispondente campo esterno evitando così sia valore null che il valore duplicato.