Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    [OLEDB] Eseguire una insert su Excel vuoto

    Salve, è da stamattina che combatto con un problema.

    Ho un foglio Excel con un solo Sheet interno di cui conosco il nome.

    Tramite OLEDB riesco a connettermi a questo file.

    Devo inserire dei dati tramite "INSERT INTO".

    Problema: il foglio è completamente vuoto.

    Questo perché a seconda dei casi i nomi di colonna e il numero di queste può variare.

    Es.
    Se provo con:
    codice:
    INSERT INTO [nomesheet$] values ('nome','cognome')
    Mi dice che il numero di colonne non è giusto.

    Se provo con:
    codice:
    INSERT INTO [nomesheet$] (nome,cognome) values ('nome','cognome')
    Mi dice giustamente che le colonne non esistono

    Ho provato anche ad usare nomi tipo A o A1 ma niente.

    Visto che ho cercato molto sul web e tutti gli esempi partono dal concetto che almeno la prima riga è riempita... mi domando... ma sarà possibile fare quello che voglio?

    Grazie

  2. #2

    La follia

    Ho infine risolto dopo eoni di tentativi e ricerche andate male, è stato un bagno di sangue.

    La soluzione si divide in questi Step.

    Premessa:

    Il foglio Excel vuoto deve avere almeno un Foglio di calcolo, il nome lo potete modificare ma non metteteci spazi, che neanche le quadre vi salverebbero. Cmq non è ammesso un Excel senza fogli quindi per forza almeno uno ci sarà.


    Step 1 - Collegamento al file XLS:
    codice:
    OleDbConnection oc=new OleDbConnection();
    oc.ConnectionString=@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=FileXLS;Extended Properties=" + Convert.ToChar(34).ToString() +"Excel 8.0;Imex=2;HDR=Yes;"+ Convert.ToChar(34).ToString();
    oc.Open();
    E' un estratto del mio codice (non sono sicuro se al 100% corretto visto che è epurato);


    Step 2 - Pulizia:
    Onde evitare la presenza di dati si esegue:
    codice:
    OleDbCommand ocom=new OleDbCommand();
    ocom.Connection=oc;
    ocom.CommandText="drop table [NomeFoglio$]";
    ocom.ExecuteNonQuery();
    Dovrebbe essere un passaggio inutile ma melius abundare quam deficere.

    Attenzione, molti avranno notato che ho usato DROP TABLE e non DELETE o TRUNCATE.
    E quì è la follia, DELETE e TRUNCATE non funzionano, danno errore, mentre DROP TABLE invece di fare quello che uno ci si aspetta (ovvero far sparire dalla faccia della Terra il Foglio) semplicemente lo svuota.

    Quindi attenzione, una volta creato un nuovo Foglio ve lo terrete per sempre, da OLEDB non si cancella.


    Step 3 - Definizione colonne:
    codice:
    ocom.CommandText="CREATE TABLE [NomeFoglio$]([Colonna1] VARCHAR(255),[Colonna2] VARCHAR(255))";
    ocom.ExecuteNonQuery();
    Potete creare i campi che volete e del tipo che preferite, l'operazione inserirà una prima riga con i nomi delle colonne.

    Ma attenzione, di nascosto questa operazione (non mi chiedetà perché, sarà un baco) inserirà subito sotto la prima riga una riga vuota.
    Se fate una insert secca subito dopo si partirà dalla terza riga, non dalla seconda.


    Step 4 - Riempimento:
    Visto il problema di cui sopra:
    codice:
    ocom.CommandText="select * from [NomeFoglio$]";
    OleDbDataReader or=ocom.ExecuteReader();
    if(or.Read())
    {
        or.Close();
        ocom.CommandText="update [NomeFoglio$] set [Colonna1]='Valore',[Colonna2]='Valore'"
        //Riempo la riga vuota con i miei dati
    }
    else
    {
        or.Close();
        ocom.CommandText="insert into [Fast_Report$] ([Colonna1],[Colonna2]) values ('Valore','Valore')";
    }
    ocom.ExecuteNonQuery();
    //Proseguire poi con le insert secche:
    ocom.CommandText="insert into [Fast_Report$] ([Colonna1],[Colonna2]) values ('Valore','Valore')";
    ocom.ExecuteNonQuery();
    //..................//
    E' follia ma è così, visto che forse è un bug che si potrebbe verificare o no per sicurezza ho fatto una select di controllo per fare insert secca o update.

    Spero di essere stato d'aiuto

  3. #3
    Utente di HTML.it L'avatar di Brainjar
    Registrato dal
    Nov 2004
    Messaggi
    1,162
    Non è un bug.
    Quando apri la connessione puoi scecificare se scrivere/leggere l'header dei campi,
    ossia i nomi 'Colonna 1' ecc.. tanto per intenderci.
    Se prima di scivere con la insert apri la connessione con :

    codice:
    +"Excel 8.0;Imex=2;HDR=Yes;"+
    allora ti inserisce, giustamente, la riga vuota che sarebbe quella dell'intestazione.

    Per evitare questo in fase di scrittura apri la connessione con :

    codice:
    +"Excel 8.0;Imex=2;HDR=No;"+
    Visto che comunque le intestazioni le crei con "CREATE TABLE .....".

    In fase di lettura, ricordati di aprire la connessione con :

    codice:
    +"Excel 8.0;Imex=2;HDR=Yes;"+
    In questo modo ti 'salta' la riga colonne e legge solo quelle dei dati in base alla
    'SELECT .... " che definisci.
    Ciao, Brainjar

  4. #4
    Quindi in sostanza dovrei prima aprire una connessione HDR=No e fare la create table, poi chiudere e riaprire con HDR=Yes per sfruttare le intestazioni?

  5. #5
    Utente di HTML.it L'avatar di Boolean
    Registrato dal
    Oct 2005
    Messaggi
    758
    Giusto per completezza, utilizzando OLEDB le colonne in Excel possono essere identificate tranquillamente senza per forza definire prima la tabella con le intestazioni di colonna, visto che basta chiamarle con il loro indice numerico preceduto dalla lettera F, in pratica mutuando il tuo esempio iniziale:

    codice:
    INSERT INTO [nomesheet$] (F1, F2) values ('nome','cognome')
    a questo punto, utilizzando anche l'accorgimento di Brainjar per quanto riguarda le intestazioni di colonna, credo tu possa risparmiare un bel po' di codice

    Boolean

  6. #6
    Avevo provato a fare una insert su F1 ma mi piazzava il tutto nella 3° riga, ma forse è per lo stesso motivo di cui sopra.

    TNX

  7. #7
    Purtroppo no, non funziona.

    Ho convertito la stringa di connessione in
    codice:
    oc.ConnectionString=@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=FileXLS;Extended Properties=" + Convert.ToChar(34).ToString() +"Excel 8.0;Imex=2;HDR=No;"+ Convert.ToChar(34).ToString();
    Ma non va.

    Ho saltato tutti gli step fino ad arrivare all'insert dei dati, basandomi su quanto detto avrebbe dovuto funzionare.

    Invece di scrivere
    codice:
    insert into [Foglio$] ([Colonna1],[Colonna2]) values ('Valore','Valore')
    Ho scritto
    codice:
    insert into [Foglio$] ([F1],[F2]) values ('Valore','Valore')
    Purtroppo mi dice che il campo F2 non è presente, praticamente mi prende solo il campo F1.

    Per caso da qualche parte devo definire il numero di campi del foglio di calcolo?

    Tnx

  8. #8
    Utente di HTML.it L'avatar di Boolean
    Registrato dal
    Oct 2005
    Messaggi
    758
    Sinceramente l'unica volta che mi è servita una cosa del genere, ho dovuto compiere solo una SELECT, ed ha funzionato senza problemi. Non so se questo sistema può avere controindicazioni eseguendo una INSERT.
    Al limite, quello che proverei, è tentare di eseguire la INSERT, anzichè sul foglio intero, su una selezione in modo che sia implicitamente definito lo spazio dei campi:

    codice:
    INSERT INTO [NomeDelFoglio$A1:B5000] (F1, F2) VALUES ('Valore', 'Valore')
    Boolean

  9. #9
    No, non funziona, però la cosa è alquanto strana, sulla direzione di F1 etc. ho cercato per bene, ho trovato una pagina della guida microsoft che dice di usare F1, F2 etc, come nulla fosse, come se fosse insito il fatto che poi funziona.

    Peccato che sia se uso HDR=No che se uso HDR=Yes mi riconosce solo F1 come colonna buona...

    Ad esempio se scrivo [codice]insert into [temp$A1:C1] (F1,F2,F3) values ('Codice','Cognome','Nome')[/codice]
    o anche[codice]insert into [temp$] (F1,F2,F3) values ('Codice','Cognome','Nome')[/codice]

    Mi sempre e comunque che non riconosce la colonna F2 (e di conseguenza tutte quelle che vengono dopo).

  10. #10
    Utente di HTML.it L'avatar di Brainjar
    Registrato dal
    Nov 2004
    Messaggi
    1,162
    Un archivio Excel deve essere inizializzato per inserire i dati per cui la CREATE la devi
    per forza eseguire.
    Dopodichè funziona correttamente l'istruzione SQL :

    codice:
    "insert into [Sheet1$] ([F1],[F2]) values ('1','2')"
    Ciao, Brainjar

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.