2014-03-25 60 views
0

新的VB程序員在這裏。我正在使用下面的方法將SQL表導出到Excel文件。但是,當我在Excel中創建文件時,由於被轉換爲數字而不是文本,我的主鍵的前導零缺失。這是由於數據表中的信息來自excel。我想知道我能做些什麼來保持我的領先零。SQL中導出零缺少導出到Excel循環

僅供參考 - 我的主鍵是6位數字,只有少數人在開始時缺少一個0。還有很多其他的行和列在第一列完成後都可以放入excel文件。它只是我需要以某種方式更改格式的第一列主鍵。

另外,我使用這個excel文件,然後上傳到SQL和一些主鍵上的缺少0 maks我的程序創建一個新的記錄。

我想主要的變化可以在這裏發生,但我無法弄清楚如何做到這一點:

   'Export the Columns to excel file 
       For Each dc In datatableMain.Columns 
        colIndex = colIndex + 1 
        oSheet.Cells(1, colIndex) = dc.ColumnName 
       Next 

       For Each dr In datatableMain.Rows 
        rowIndex = rowIndex + 1 
        colIndex = 1 

        For Each dc In datatableMain.Columns 
         colIndex = colIndex + 1 
         oSheet.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName) 
        Next 
       Next 

完整的代碼下面:

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 

     Dim dataAdapter As New SqlClient.SqlDataAdapter() 
     Dim dataSet As New DataSet 
     Dim command As New SqlClient.SqlCommand 
     Dim datatableMain As New System.Data.DataTable() 
     Dim connection As New SqlClient.SqlConnection 


     connection.ConnectionString = "Server=myserver;Database=mydatabase;User Id=xxxx;Password=xxxxx" 
     command.Connection = connection 
     command.CommandType = CommandType.Text 
     'You can use any command select 
     command.CommandText = "Select * from MYTABLE" 
     dataAdapter.SelectCommand = command 


     Dim f As FolderBrowserDialog = New FolderBrowserDialog 
     Try 
      If f.ShowDialog() = DialogResult.OK Then 
       'This section help you if your language is not English. 
       System.Threading.Thread.CurrentThread.CurrentCulture = _ 
       System.Globalization.CultureInfo.CreateSpecificCulture("en-US") 
       Dim oExcel As Excel.Application 
       Dim oBook As Excel.Workbook 
       Dim oSheet As Excel.Worksheet 
       oExcel = CreateObject("Excel.Application") 
       oBook = oExcel.Workbooks.Add(Type.Missing) 
       oSheet = oBook.Worksheets(1) 

       Dim dc As System.Data.DataColumn 
       Dim dr As System.Data.DataRow 
       Dim colIndex As Integer = 0 
       Dim rowIndex As Integer = 0 

       'Fill data to datatable 
       connection.Open() 

       dataAdapter.Fill(datatableMain) 
       connection.Close() 

       'Export the Columns to excel file 
       For Each dc In datatableMain.Columns 
        colIndex = colIndex + 1 
        oSheet.Cells(1, colIndex) = dc.ColumnName 
       Next 

       For Each dr In datatableMain.Rows 
        rowIndex = rowIndex + 1 
        colIndex = 1 

        For Each dc In datatableMain.Columns 
         colIndex = colIndex + 1 
         oSheet.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName) 
        Next 
       Next 

       'Set final path 
       Dim fileName As String = "\" + fname.Text + ".xlsx" 
       Dim finalPath = f.SelectedPath + fileName 
       txtPath.Text = finalPath 
       oSheet.Columns.AutoFit() 
       'Save file in final path 
       oBook.SaveAs(finalPath, Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing, _ 
       Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, _ 
       Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing) 

       'Release the objects 
       ReleaseObject(oSheet) 
       oBook.Close(False, Type.Missing, Type.Missing) 
       ReleaseObject(oBook) 
       oExcel.Quit() 
       ReleaseObject(oExcel) 
       'Some time Office application does not quit after automation: 
       'so i am calling GC.Collect method. 
       GC.Collect() 

       MessageBox.Show("Exported!") 

      End If 
     Catch ex As Exception 
      MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK) 
     End Try 
    End If 
End Sub 
Private Sub ReleaseObject(ByVal o As Object) 
    Try 
     While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) 
     End While 
    Catch 
    Finally 
     o = Nothing 
    End Try 
End Sub 
+0

嘗試設置單元格的NumberFormat屬性設置爲「000000」。 – Lauren

+0

我會怎麼做只爲包含主鍵的第一列?我的所有其他列完全格式化。 – Infinite8Self

+0

Telestia建議的方式最好。您正在設置Excel列的格式。設置爲「@」用於文本格式,將其設置爲「000000」會給您一個前導0的數字,填充到6個位置。 – Lauren

回答

3

其實我只是有一個類似的問題有關10分鐘前!我需要從一本書到另一本書中得到一個30位數的數字,並且它充滿了一切。嘗試在寫入單元格之前設置列的格式。我的代碼是Worksheets(i).Range("D:D").NumberFormat = "@"這將告訴Excel將數據「按原樣」進行互換,而不是試圖猜測您想要的內容。

+0

工作就像一個魅力Telestia。謝謝你的朋友! – Infinite8Self

+0

我很高興!這意味着它*實際上*工作,而不是我只是方便地打破工作方向的東西! – Telestia

0

我發現這個問題尋找解決這個問題在我有一個泛型函數,這是由我創建的幾個程序使用。由於各種各樣的數據源,我無法硬編碼哪一列來設置NumberFormat。爲了解決它,我利用了我必須輸出列標題的循環。我的代碼是低於那些需要更多的動態解決方案。注意,有一對夫婦引用「EL」這是在同一個解決方案自定義錯誤日誌對象,這剛好可以忽略不計/修改的一個實例:

''' <summary> 
''' Function to take a data table and output its contents to an Excel spreadsheet. Returns a string with any errors (Nothing if successful) 
''' </summary> 
''' <param name="D">The datatable to be output</param> 
''' <param name="epath">The full file path to log errors to</param> 
''' <param name="SAName">The full file path to save the created Excel workbook to</param> 
''' <param name="Parent">The function calling for data to be output</param> 
''' <returns></returns> 
''' <remarks></remarks> 
Public Function ResOut(ByVal D As DataTable, ByVal epath As String, ByVal SAName As String, ByVal Parent As String) As String 
    ' 
    Dim res As String = "" 
    Dim E As New Microsoft.Office.Interop.Excel.Application 
    Dim wb As Microsoft.Office.Interop.Excel.Workbook = Nothing 
    Dim ws As Microsoft.Office.Interop.Excel.Worksheet = Nothing 
    Dim x As Long = 0 
    Dim f As Long = 1 
    Dim Rng As Microsoft.Office.Interop.Excel.Range = Nothing 
    Dim q As String 
    Dim Str_Columns As New List(Of String) 'Holds the list of column letters that need forced to Text format in order to retain leading zeroes in the data 
    'that will be placed there 
    'Check that the passed in table has data 
    If D.Rows.Count = 0 Then 
     res = "No data was returned by " & Parent 
    End If 

    If res = "" Then 
     'Create a workbook for the data and capture the workbook and sheet for ease of reference 
     Try 
      wb = E.Workbooks.Add 
      ws = wb.Worksheets(1) 

      'Define the range 
      q = ColNumToStr(D.Columns.Count, epath) 
      Rng = ws.Range("A2:" & q & D.Rows.Count + 1) 
     Catch ex As Exception 
      res = "Encountered an error while creating the new workbook to export the results to. No data can be returned." 
      EL.AddErr(res & " ResOut was called by " & Parent & ". Error Details: " & ex.Message, epath) 
     End Try 

     'Fill in headers 
     If res = "" Then 
      Try 
       For Each c As DataColumn In D.Columns 
        ws.Range("A1").Offset(0, x).Value = c.ColumnName 
        x = x + 1 
       Next 
      Catch ex As Exception 
       res = "Encountered an error while filling in the column headers. This will prevent any data from being returned." 
       EL.AddErr(res & " ResOut was called by " & Parent & ". Error Details: " & ex.Message, epath) 
      End Try 
     End If 

     'Setup the step & frequency for the Step Progress bar 
     'Dim t() As Long = s.StatSetup(QR.Rows.Count, 58, "Query Runner\ResOut\" & QName, Replace(My.Settings.EPath, "<user>", Environment.UserName) & DStamp() & " Query Scheduler Log.txt") 
     'f = t(0) 
     'SProg.Step = t(1) 

     'Create the array 
     Dim OArr(D.Rows.Count, x) As Object 

     'Convert the datatable to a 2D array 
     If res = "" Then 
      Try 
       'Fill it 
       x = 0 
       For r As Long = 0 To D.Rows.Count - 1 Step 1 
        Dim dr As DataRow = D.Rows(r) 

        For c As Integer = 0 To D.Columns.Count - 1 Step 1 
         OArr(r, c) = dr.Item(c).ToString 

         'Check if this item is a # with leading zeroes (making sure we haven't already added the column to the list of such columns) 
         If Not (Str_Columns.Contains(ColNumToStr(c + 1, epath))) And Strings.Left(dr.Item(c), 1) = "0" Then 
          Str_Columns.Add(ColNumToStr(c + 1, epath)) 
         End If 'else the column is in the list already or the item does not dictate it's inclusion 
        Next 
        x = x + 1 
       Next 
      Catch ex As Exception 
       res = "Encountered an error while outputing the " & x + 1 & "-th record of " & D.Rows.Count & ". No data will be output." 
       EL.AddErr(res & " ResOut was called by " & Parent & ". Error Details: " & ex.Message, epath) 
      End Try 
     End If 

     'output the array to the target range 
     If res = "" Then 
      'First force Text format where needed to retain leading zeroes 
      Try 
       For Each c As String In Str_Columns 
        q = c 
        ws.Range(c & ":" & c).NumberFormat = "@" 
       Next 
      Catch ex As Exception 
       res = "Encountered an error while changing column " & q & " to TEXT in order to retain leading zeroes in the " & ws.Range(q & 1).Value & "data." 
       E.Visible = True 
       wb.Activate() 
       EL.AddErr(res & " ResOut was called by " & Parent & ". Error Details: " & ex.Message & Chr(10) & Chr(10) & "Inner Exception: " & ex.InnerException.Message _ 
          , epath) 
      End Try 

      Try 
       Rng.Value = OArr 

       'Save the workbook 
       wb.SaveAs(SAName) 
       wb.Close(SaveChanges:=False) 
      Catch ex As Exception 
       res = "Encountered an error during the export of the results. Some data may have been exported. Review the contents of the Excel workbook that will " _ 
        & "be visible following this message for more details." 
       E.Visible = True 
       wb.Activate() 
       EL.AddErr(res & " ResOut was called by " & Parent & ". Error Details: " & ex.Message, epath) 
      End Try 
     Else 
      'Close the workbook without saving 
      wb.Close(SaveChanges:=False) 
     End If 

     'Cleanup the application 
     Try 
      E.Quit() 
      System.Runtime.InteropServices.Marshal.ReleaseComObject(E) 
      E = Nothing 
      wb = Nothing 
      ws = Nothing 
      Rng = Nothing 
      OArr = Nothing 
      f = Nothing 
      x = Nothing 
     Catch ex As Exception 
      EL.AddErr("Encountered an error while cleaning up the resources used in JMLib\ResOut. ResOut was called by " & Parent & ". Error Details: " & ex.Message, epath) 
     End Try 
    End If 

    Return res 
End Function