2016-08-03 3 views
1

Привет, я пытаюсь преобразовать dbf в xls, но проблема в том, что только половина данных преобразуется. Может кто-нибудь помочь мне и узнать, в чем проблема?Только половина данных dbf преобразуется в xls

Вот образцовая фотография dbf, которую я конвертирую. enter image description here

здесь преобразованный файл только 2 данные enter image description here

UPDATE Вот еще один пример, как просили.

Я конвертирую этот файл dbf. enter image description here

это результат enter image description here

вот код.

static Missing mv = Missing.Value; 
     private void button1_Click(object sender, EventArgs e) 
     { 
      DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog. 
      if (result == DialogResult.OK) // Test result. 
      { 
       textBox1.Text = openFileDialog1.FileName; 



      } 
     } 

private void button2_Click(object sender, EventArgs e) 
     { 
      string constr = "Provider=VFPOLEDB.1;Data Source=" + Directory.GetParent(textBox1.Text).FullName; 
      string ExcelFileName = AppDomain.CurrentDomain.BaseDirectory + System.IO.Path.GetFileNameWithoutExtension(textBox1.Text) + ".xls"; 
      using (OleDbConnection con = new OleDbConnection(constr)) 
      { 
       var sql = "select * from " + Path.GetFileName(textBox1.Text) + ";"; 
       OleDbCommand cmd = new OleDbCommand(sql, con); 
       DataTable dt = new DataTable(); 
       try 
       { 
        con.Open(); 
       } 
       catch (Exception ex) 
       { 

        MessageBox.Show("Error connecting database: " + ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
        return; 
       } 
       if (con.State == ConnectionState.Open) 
       { 
        OleDbDataAdapter da = new OleDbDataAdapter(cmd); 
        MessageBox.Show("Reading database... ", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); 
        da.Fill(dt); 
        MessageBox.Show("Completed.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); 
       } 
       if (con.State == ConnectionState.Open) 
       { 
        try 
        { 
         con.Close(); 
        } 
        catch { } 
       } 

       if (dt != null && dt.Rows.Count > 0) 
       { 
        GenerateExcel(dt, ExcelFileName); 
       } 
      } 

     } 

static void GenerateExcel(DataTable sourceDataTable, string ExcelFileName) 
     { 
      MessageBox.Show("Generating Excel File...", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); 


      Excel.Application excelApp = new Excel.Application(); 
      Excel.Workbook wkb = excelApp.Workbooks.Add(mv); 
      Excel.Worksheet wks = wkb.Sheets[1]; 

      for (int i = 0; i < sourceDataTable.Columns.Count; ++i) 
      { 
       ((Excel.Range)wks.Cells[1, i + 1]).Value = sourceDataTable.Columns[i].ColumnName; 
      } 
      Excel.Range header = wks.get_Range((object)wks.Cells[1, 1], (object)wks.Cells[1, sourceDataTable.Columns.Count]); 
      header.EntireColumn.NumberFormat = "@"; 

      object[,] sourceDataTableObjectArray = new object[sourceDataTable.Rows.Count, sourceDataTable.Columns.Count]; 
      for (int row = 0; row < sourceDataTable.Rows.Count; ++row) 
      { 
       for (int col = 0; col < sourceDataTable.Columns.Count; ++col) 
       { 
        sourceDataTableObjectArray[row, col] = sourceDataTable.Rows[row][col].ToString(); 
       } 
      } 
      ((Excel.Range)wks.get_Range((object)wks.Cells[2, 1], (object)wks.Cells[sourceDataTable.Rows.Count, sourceDataTable.Columns.Count])).Value2 = sourceDataTableObjectArray; 
      header.EntireColumn.AutoFit(); 
      header.Font.Bold = true; 
      wks.Application.ActiveWindow.SplitRow = 1; 
      wks.Application.ActiveWindow.FreezePanes = true; 
      wks.SaveAs(ExcelFileName, Excel.XlFileFormat.xlExcel8, mv, mv, mv, mv, mv, mv, mv, mv); 
      wks = null; 
      wkb = null; 
      excelApp.Quit(); 
      MessageBox.Show("Completed.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 
    } 
+0

Код выглядит хорошо. Вы можете добавить некоторые записи, чтобы вы знали, в какой момент вы «потеряете» эти строки. Пример: использование System.Diagnostics; Debug.WriteLine ("dt имеет <" + dt.Rows.Count + "> строки в этой точке"); –

+0

@ Ulli Schmid не знает, что делать :( – nethken

+0

Если я посмотрю данные на верхнем скриншоте, очевидно, какие данные не будут проходить. Вы уверены, что данные в первых 7 строках представляют интерес? Может быть, это просто данные заголовка таблицы, которые вам не нужны в выводе? –

ответ

1

Один вопрос, который объясняет, почему последняя строка продолжает получать удалены:

((Excel.Range)wks.get_Range((object)wks.Cells[2, 1], (object)wks.Cells[sourceDataTable.Rows.Count, sourceDataTable.Columns.Count])).Value2 = sourceDataTableObjectArray; 

должен быть изменен на

((Excel.Range)wks.get_Range((object)wks.Cells[2, 1], (object)wks.Cells[sourceDataTable.Rows.Count + 1, sourceDataTable.Columns.Count])).Value2 = sourceDataTableObjectArray; 

Объяснение: Диапазон Excel не является достаточно большим (1 слишком мал), чтобы принять полный sourceDataTable.

Что касается других вопросов (видно в примере 1) - проблема лежит в базе данных. Ваши «отсутствующие» данные не включены в возврат запроса к базе данных, поскольку эти строки помечены как «удаленные» в файлах .dbf. Этот источник:

Manipulate the 'deleted record' flag on DBF files

приводит меня к мысли, что вы можете решить ваши проблемы путем изменения

var sql = "select * from " + Path.GetFileName(textBox1.Text) + ";"; 

в

string tableName = Path.GetFileName(textBox1.Text) 
var sql = "select * from Deleted(" + tableName + ") UNION select * from " + tableName + ";"; 

Я не являюсь на самом деле не эксперт по вашей DBF базы данных и SQL если это не сработает, вы должны опубликовать это как новый вопрос.

+0

Как вы сказали, это только показывает, сколько данных преобразуется: # – nethken

+0

Что такое вывод if вы регистрируетесь? –

+0

Я конвертирую файл dbf с 27 строками, а затем вывод «dt имеет <7> строк в точке 1.sourceDataTable имеет <7> строк в точке 2 – nethken