2012-02-14 74 views
1

我將展示一些人爲的例子,請耐心等待。應用函數後保持單元格文本格式化

我們的產品利用CSV文件創建過渡數據,在Excel用戶界面和Java程序之間發送數據,並將其轉移到SQL後端。我們有一個VBA腳本,可按以下順序處理所有Excel工作:

在單個Excel文檔中將所有8個CSV文件加載到8個工作表中。然後通過數據執行以下操作的批次迭代:

'Loop over data: 
    Dim r As Range 
    ... 
    r.NumberFormat = "General" 
    r.Formula = r.Formula 
'End loop 

這會導致整個片材與來自CSV數據來填充,用數目的細胞具有文本的外觀和Excel公式保持未計算的。運行r.Formula = r.Formula觸發所有函數進行正確評估。唯一的問題是數字格式。

CSV文件有時包含嵌套的CSV。例如,單個單元格可能包含「1,2,3,15,654」這些單元格始終顯示爲文本。但是,有一個邊緣情況,其中單元格可能是漂亮的打印數字,例如「10,456,345」Excel將在評估所有函數後將這些數字轉換爲數字單元格,並刪除所有逗號。儘管文檔中的20,000行左右是正確的,但這影響了4行左右,從而打破了整個系統。

有沒有辦法觸發Excel來評估從CSV的功能,而不必完全從VBA中更改單元格格式?由於Java CSV生成器由不同的部門處理,因此將格式從CSV更改爲SYLK不是一種選擇。

+0

是否指CSV文件包含Excel公式(例如,「= R1C1」或「= A1」)? – assylias 2012-02-14 16:47:03

+0

您是否嘗試過使用'r.NumberFormat =「@」'將單元格定義爲文本? – 2012-02-14 16:52:12

+0

@assylias是的,它包含Excel公式。 Java程序根據需要生成正確的公式,並在正確的位置生成CSV文件。 r.Formulas = r.Formulas觸發它們進行評估。 – Reivax 2012-02-14 18:02:01

回答

1

您可以將所有單元格的格式設置爲文本(Cells.NumberFormat =「@」),然後遍歷它們並在以'='開頭的單元格上使用您的代碼。 如果性能是一個問題,您應該將工作表內容放入數組中,在數組上工作並將其放回工作表。 如果您發佈更多的代碼和示例數據,人們將能夠仔細觀察。

EDIT

例如,把下列值在列A(從A1到A4) 「工作表Sheet」 的,具有文本格式:

13246 
13564,4654,4565 
654 
=A1+A3 

,並使用以下代碼:

Sub test() 

    Dim a As Variant 
    Dim result As Variant 

    a = Sheets("Sheet1").UsedRange 
    ReDim result(1 To UBound(a, 1), 1 To UBound(a, 2)) As Variant 

    For i = 1 To UBound(a, 1) 
     For j = 1 To UBound(a, 2) 
     If Left(a(i, j), 1) = "=" Then 
      result(i, j) = a(i, j) 
     Else 
      result(i, j) = "'" & a(i, j) 
     End If 
     Next j 
    Next i 

    Sheets("Sheet1").Cells(1, 2).Resize(UBound(result, 1), UBound(result, 2)) = result 

End Sub 

結果被放入列B和是:

13246 
13564,4654,4565 
654 
13900 
+0

將其推入數組可能更具可管理性。數組大小有上限嗎?我知道有字符串長度。 – Reivax 2012-02-16 16:16:42

+0

我不認爲有VBA限制(請參閱http://support.microsoft.com/default.aspx?scid=kb;en-us;177991),它很可能會受到您的內存限制。例如,您可以存儲數百萬個數字。 – assylias 2012-02-16 16:21:37

+0

我個人嘗試儘可能多地對陣列進行處理,因爲我一般一次處理100k ++記錄,並且它顯着提高了性能。因此,一個典型的工作流程將是:將數據從工作表讀取到數組中,處理數據並將結果放入另一個數組,將該新數組複製到目標工作表。 – assylias 2012-02-16 16:24:47

1

我有一種可能適用的替代技術。

我創建了一個包含26,000個值的工作表:包含逗號和公式的字符串,數字,日期,數字。

我跑超過上述片一個環路,它的內碼是:

 ValueCell = .Cells(RowCrnt, ColCrnt).Formula 
    If IsNumeric(Replace(ValueCell, ",", "")) Then 
     .Cells(RowCrnt, ColCrnt).Formula = Replace(ValueCell, ",", "|") 
    End If 

.Cells(RowCrnt, ColCrnt).Formula得到式如果單元包含一個或值,如果它沒有。如果刪除的任何逗號的值或公式是數字,我用管道替換任何逗號。

26,000個細胞需要59秒。這是否與每500行多出45秒有利?

「1,2,3,15,654」的任何值現在都是「1 | 2 | 3 | 15 | 654」,但我認爲這不是問題。如果你有嵌套的字符串,比如「ab,cd,ef」,它們仍然會包含逗號。也許測試一個領先的「=」來消除公式並自動替換其他所有的逗號將是一種可能性。

以下代碼需要78秒才能運行26,000個單元。

 ValueCell = .Cells(RowCrnt, ColCrnt).Formula 
    If Left(ValueCell, 1) <> "=" Then 
     .Cells(RowCrnt, ColCrnt).Formula = Replace(ValueCell, ",", "|") 
    End If 

希望這可以幫助,如果只是給你新的想法。

+0

這是一個很好的解決方案。我們在整個工作簿上的總運行時間是5秒,而不是每500行5秒。除了編號問題外,它的編程非常好。一分鐘內可能無法交付。使用替代分隔符可能是可以接受的,我會看看是否可以讓其他團隊將嵌套CSV中的逗號更改爲半色或其他合理的可壓縮字符。或者,也許可以讓CSV生成器/解析僅使用分號作爲嵌套分隔符。 – Reivax 2012-02-16 16:21:25

0

我提出一個替代方案,更簡單的方法:

你有沒有考慮直接從Java程序寫入到一個Excel電子表格,例如使用Apache POI?對我來說,這比整個CSV公式業務要簡單得多,不太容易出錯,並且不易出錯。

+0

是的,我有,但任務是沒有開源工具。儘管如此,這是一項愚蠢而可怕的要求。 – Reivax 2012-02-16 16:16:04

+0

那麼,只要它被編譯,它就不再是開源的了......這是多麼荒謬的要求。這就像要求代碼寫入時沒有字母「e」一樣荒謬。 – 2012-02-17 02:18:18

+0

思想是社區驅動意味着沒有支持,也沒有人確保沒有任何漏洞。我的推理是開源是確保沒有漏洞的唯一途徑,但這不是管理層的看法。顯然,他們希望有人分配責任,如果他們需要。使用POI庫就屬於這種情況。 MySQL也是如此,但Oracle是允許的。 – Reivax 2012-02-21 19:28:18

相關問題