2009-09-22 7 views
5

Quando la prima cella di un foglio Excel da importare utilizzando ExcelStorage.ExtractRecords è vuota, il processo ha esito negativo. Vale a dire. Se i dati iniziano da col 1, riga 2, se la cella (2,1) ha un valore vuoto, il metodo fallisce.Filehelpers ExcelStorage.ExtractRecords ha esito negativo quando la prima cella è vuota

Qualcuno sa come aggirare questo? Ho provato ad aggiungere un attributo FieldNullValue alla classe di mappatura senza fortuna.

Here è un progetto di esempio che mostrano il codice con problemi

speranza che qualcuno mi può aiutare o punto in qualche direzione.

Grazie!

+0

Non l'ho davvero usato, ho solo guardato la libreria qualche tempo fa: può l'attributo FieldOptional help? –

risposta

4

Sembra che tu sia incappato in un problema in FileHelpers.

Quello che succede è che il metodo ExcelStorage.ExtractRecords utilizza un controllo di cella vuoto per vedere se ha raggiunto la fine del foglio. Questo può essere visto nel codice sorgente ExcelStorage.cs:

while (CellAsString(cRow, mStartColumn) != String.Empty) 
{ 
    try 
    { 
     recordNumber++; 
     Notify(mNotifyHandler, mProgressMode, recordNumber, -1); 

     colValues = RowValues(cRow, mStartColumn, RecordFieldCount); 

     object record = ValuesToRecord(colValues); 
     res.Add(record); 

    } 
    catch (Exception ex) 
    { 
     // Code removed for this example 
    } 
} 


Quindi, se la colonna inizio di ogni riga è vuota, allora si assume che il file è fatto.

Alcune opzioni per aggirare il problema:

  1. Non mettere tutte le celle vuote nella prima posizione di colonna.
  2. Non utilizzare Excel come formato file - convertire prima in CSV.
  3. Verificare se è possibile ottenere una patch dallo sviluppatore o applicare la patch all'origine.

I primi due sono soluzioni alternative (e non molto buone). La terza opzione potrebbe essere la migliore, ma qual è la fine della condizione del file? Probabilmente un'intera riga vuota sarebbe un controllo abbastanza buono (ma anche quello potrebbe non funzionare in tutti i casi tutto il tempo).

+0

Grazie a Tuzo! Proverò a risolverlo, mi hai dato alcune informazioni utili. – Sebastian

4

Grazie all'aiuto di Tuzo, ho potuto trovare un modo per risolvere questo problema. Ho aggiunto un metodo alla classe ExcelStorage per modificare la condizione di fine del tempo. Invece di guardare la prima cella per il valore vuoto, guardo tutte le celle della riga corrente per essere vuote. Se questo è il caso, restituisci false al momento. Questa è la variazione alla parte mentre di ExtractRecords:

while (!IsEof(cRow, mStartColumn, RecordFieldCount)) 

anziché

while (CellAsString(cRow, mStartColumn) != String.Empty) 

IsEOF è un metodo per controllare l'intera riga sia vuota:

private bool IsEof(int row, int startCol, int numberOfCols) 
    { 
     bool isEmpty = true; 
     string cellValue = string.Empty; 

     for (int i = startCol; i <= numberOfCols; i++) 
     { 
      cellValue = CellAsString(row, i); 
      if (cellValue != string.Empty) 
      { 
       isEmpty = false; 
       break; 
      } 
     } 

     return isEmpty; 
    } 

Naturalmente se l'utente lascia una riga vuota tra due righe di dati, le righe dopo quella non verranno elaborate, ma penso che sia una buona cosa continuare a lavorare su questo.

Grazie

+1

Grazie, ho preso il tuo codice un ulteriore passo avanti. Dovevo essere in grado di saltare le righe vuote –

+0

Da allora è stato aggiunto alla sorgente FileHelpers in Github. Ho anche commesso un'altra modifica a FileHelpers ExcelStorage: "consenti ai fogli di Excel di contenere una o più righe vuote senza che il Reader si fermi su quelle file finché non viene superato un massimo (ExcelReadStopAfterEmptyRows)" vedi: https://github.com/MarcosMeli/ FileHelpers/tirare/4 – rohancragg

3

avevo bisogno di essere in grado di saltare righe vuote, così ho aggiunto il seguente codice alla biblioteca FileHelpers.Ho preso Sebastian s' IsEof codice e rinominato il metodo per IsRowEmpty e cambiato il ciclo in ExtractRecords da ...

while (CellAsString(cRow, mStartColumn) != String.Empty) 

a ...

while (!IsRowEmpty(cRow, mStartColumn, RecordFieldCount) || !IsRowEmpty(cRow+1, mStartColumn, RecordFieldCount)) 

Ho poi cambiato questo ...

colValues = RowValues(cRow, mStartColumn, RecordFieldCount); 

object record = ValuesToRecord(colValues); 
res.Add(record); 

a questo ...

bool addRow = true; 

if (Attribute.GetCustomAttribute(RecordType, typeof(IgnoreEmptyLinesAttribute)) != null && IsRowEmpty(cRow, mStartColumn, RecordFieldCount)) 
{ 
    addRow = false; 
} 

if (addRow) 
{ 
    colValues = RowValues(cRow, mStartColumn, RecordFieldCount); 

    object record = ValuesToRecord(colValues); 
    res.Add(record); 
} 

Ciò che mi dà è la possibilità di saltare singole righe vuote. Il file verrà letto finché non verranno trovate due righe vuote successive

Problemi correlati