2011-08-13 91 views
1

我有一個包含AccountNumber,Year和Month的多列的DataTable。我將此表中的信息導出到Excel工作簿。由於這個表格可能會非常大,我必須檢查表格中的記錄數(因爲Excel只能有65536行或類似的東西)如果原始表格足夠小,我需要把所有記錄如果一個工作表中的記錄太多,我需要根據AccountNumber將記錄分成多個工作表。此外,如果某個特定AccountNumber的記錄太多,那麼我需要將該AccountNumber分成多個工作表。基於年度如果一個特定的年份仍然有太多記錄,然後我必須按月分裂他們從數據表中獲取唯一記錄的有效方法

例如:

如果我一共有500000條記錄,我必須通過賬戶號碼讓它們分割:

工作表名稱----記錄數

  • 1111 ---- 150000
  • 2222 ---- 50000
  • 3333 ---- 100000

然後我需要根據年份將帳戶1111和3333分成多個工作表。那麼我有這樣的事情:

表姓名----數紀錄

  • 1111年至2010年---- 50000
  • 1111年至2011年---- 100000
  • 2222 ---- 50000
  • 3333-2010 ---- 50000
  • 3333-2011 ---- 50000

之後,由於1111年至2011年仍然過大,我不得不拆分一個基於一個月,終於給:

表姓名----號碼記錄

  • 1111年至2010年的--- - 50000
  • 1111-201105 ---- 30000
  • 1111-201106 ---- 30000
  • 1111-201107 ---- 40000
  • 2222 ---- 50000
  • 3333-2 010 ---- 50000
  • 3333-2011 ---- 50000

正被用於創建Excel文件的代碼是被寫了我公司的一個項目。爲了簡單起見,該函數接受DataTable並以Excel電子表格的格式將記錄寫出到DataTable中。關於如何在不再調用數據庫的情況下做到這一點的任何想法?提前致謝。

+0

僅供參考,Excel 2007和更高版本可以有100萬行。 –

+0

是的,但我們公司的一些個人電腦仍在使用2003 –

+0

似乎它可能會更容易,只是升級他們;) –

回答

0

您可以使用LINQ-to-DataSet分組相應的DataRows並將其添加到與更少的行超過65536

分離

看一看這方面的工作樣本也產生了正確的文件/數據表 - 姓名:

Private Shared sampleAccountNumbers As List(Of Int32) = {1111, 2222, 3333, 4444}.ToList 
Private Const MAX_ROWS = 65536 
Private tblSource As New DataTable() 
Private allResultTables As New List(Of DataTable) 

Private Sub SplitTableRows() 
    Dim accQuery = _ 
     From row In tblSource 
     Group row By AccountNumber = row("AccountNumber") Into AccNumGroup = Group 
    For Each acc In accQuery 
     If acc.AccNumGroup.Count > MAX_ROWS Then 
      Dim yearQuery = _ 
       From row In acc.AccNumGroup 
       Group row By Year = row("Year") Into YearGroup = Group 
      For Each y In yearQuery 
       If y.YearGroup.Count > MAX_ROWS Then 
        Dim monthQuery = _ 
         From row In y.YearGroup 
         Group row By Month = row("Month") Into MonthGroup = Group 
        For Each m In monthQuery 
         If m.MonthGroup.Count > MAX_ROWS Then 
          'split by days or whatever...' 
         Else 
          Dim tblMonth = m.MonthGroup.CopyToDataTable() 
          tblMonth.TableName = String.Format("{0}-{1}{2}", acc.AccountNumber, y.Year, m.Month) 
          allResultTables.Add(tblMonth) 
         End If 
        Next 
       Else 
        Dim tblYear = y.YearGroup.CopyToDataTable() 
        tblYear.TableName = String.Format("{0}-{1}", acc.AccountNumber, y.Year) 
        allResultTables.Add(tblYear) 
       End If 
      Next 
     Else 
      Dim tblAcc = acc.AccNumGroup.CopyToDataTable() 
      tblAcc.TableName = acc.AccountNumber 
      allResultTables.Add(tblAcc) 
     End If 
    Next 
End Sub 

Private Sub BtnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStart.Click 
    InitSourceDataTable() 
    If tblSource.Rows.Count > MAX_ROWS Then 
     SplitTableRows() 
    Else 
     allResultTables.Add(tblSource) 
    End If 
    For Each tbl In allResultTables 
     'call your generate-excel-method...' 
    Next 
End Sub 

Private Sub InitSourceDataTable() 
    Dim rndAccNum As New Random(Date.Now.Millisecond) 
    Dim rndYear As New Random(Date.Now.Millisecond) 
    Dim rndMonth As New Random(Date.Now.Millisecond) 
    tblSource.Columns.Add(New DataColumn("ID", GetType(Integer))) 
    tblSource.Columns.Add(New DataColumn("AccountNumber", GetType(Integer))) 
    tblSource.Columns.Add(New DataColumn("Year", GetType(Integer))) 
    tblSource.Columns.Add(New DataColumn("Month", GetType(Integer))) 
    For i As Int32 = 1 To 500000 
     Dim newRow = tblSource.NewRow 
     newRow("ID") = i 
     newRow("AccountNumber") = sampleAccountNumbers(rndAccNum.Next(0, sampleAccountNumbers.Count)) 
     newRow("Year") = rndAccNum.Next(2005, 2012) 
     newRow("Month") = rndMonth.Next(1, 13) 
     tblSource.Rows.Add(newRow) 
    Next 
End Sub 

此示例使用在2005 - 2012年期間以500.000記錄隨機4靜態AccountNumbers。由於LINQ-to-DataSet完全在內存中工作,因此它僅生成28個DataTable並在1.6秒內克隆所有DataRows。

+0

謝謝這麼多,我不得不改變一些小的細節,但這是一個很大的幫助。 –

0

您是否正在從數據庫中專門爲此操作提取數據?如果是這樣,請使用SELECT DISTINCT並將數據庫索引放在相關列上。這樣,您不必擔心它 - DBMS會爲您過濾掉重複的行。所有剩下的事情就是遍歷行並按照你的意願對它們進行分組。

如果您正在使用分組行掙扎,你可以通過子句添加COUNT()來選擇和組和DBMS會告訴你有多少行符合類別:

SELECT *, COUNT(*)AS row_count GROUP BY accountid, year, month, etc...; 

和你的行會看起來像這樣:

c1 c2 c3 row_count 
---- ---- ---- --------- 
xxx, xxx, xxx, 1 
yyy, yyy, yyy, 2 
yyy, yyy, zzz, 2 
+0

不,Excel的一代 –

+0

Excel不是數據庫Excel是正確的選擇嗎?考慮使用Access或csv文件 –

+0

它正在生成Excel報告供我們的推銷員使用 –

相關問題