【发布时间】:2015-03-31 21:35:28
【问题描述】:
我正在处理一个 5 表工作簿,其中表 5 上名为 ExportCSV 的按钮导出表 3 上的数据。更具体地说,该按钮运行一个 VBA 代码,该代码逐行检查前 3 个单元格数据。如果前三个单元格中的任何一个有数据,则选择整行。选择所有包含数据的行后,将数据逐行写入 CSV 文件(但文件本身以分号分隔)。
我遇到的问题是某些单元格格式被复制了,但有些没有。例如,使用 $ 为会计格式的单元格中的值格式正确,这意味着“$12,345,678.90”显示为“$12,345,678.90”。但是,格式为会计但没有 $ 的单元格中的值未正确写入 csv,这意味着“12,345,678.90”被写入“12345678.9”。
下面是有问题的宏。
Dim planSheet As Worksheet
Dim temSheet As Worksheet
Private Sub ExportCSV_Click()
Dim i As Integer
Dim j As Integer
Dim lColumn As Long
Dim intResult As Integer
Dim strPath As String
On Error GoTo Errhandler
Set temSheet = Worksheets(3)
i = 2
Do While i < 1001
j = 1
Do While j < 4
If Not IsEmpty(temSheet.Cells(i, j)) Then
temSheet.Select
lColumn = temSheet.Cells(2, Columns.Count).End(xlToLeft).Column
temSheet.Range(temSheet.Cells(2, 1), temSheet.Cells(i, lColumn)).Select
End If
j = j + 1
Loop
i = i + 1
Loop
Application.FileDialog(msoFileDialogFolderPicker).InitialFileName = Application.ActiveWorkbook.Path
Application.FileDialog(msoFileDialogFolderPicker).Title = "Select a Path"
Application.FileDialog(msoFileDialogFolderPicker).ButtonName = "Select Path"
intResult = Application.FileDialog(msoFileDialogFolderPicker).Show
If intResult <> 0 Then
'dispaly message box
strPath = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1)
End If
Dim X As Long, FF As Long, S() As String
ReDim S(1 To Selection.Rows.Count)
For X = 1 To Selection.Rows.Count
S(X) = Join(WorksheetFunction.Transpose(WorksheetFunction.Transpose(Selection.Rows(X).Value)), ";")
Next
FF = FreeFile
FilePath = strPath & "\Data" & Format(Now(), "yyyyMMddhhmmss") & ".csv"
Open FilePath For Output As #FF
Print #FF, Join(S, vbNewLine)
Close #FF
Errhandler:
...Error Handling Code omitted
End Sub
我需要能够复制单元格的确切格式。将 no-$ 单元格转换为 $ 单元格将不起作用,因为没有 $ 的值将用于稍后在可以处理逗号但不是 $ 的过程中的计算,并且我无法更改代码稍后计算(专有插件进行计算。)此外,行具有混合内容,这意味着行中的某些值是文本而不是数字。
【问题讨论】:
-
您将需要对
For x = 1 to Selection.Rows.Count循环进行大修。您必须对每行范围内的值数组进行逐个单元格迭代,并更新数组以包含 formatted 值(默认情况下,它将使用.Value完全不知道任何格式)。那有意义吗?如果是这样,请试一试,如果您遇到困难,我们会尽力提供帮助。 -
这确实有些道理。我想我只是想看看是否有人知道不必这样做。
-
对,我认为当您处理有条件地时,没有其他方法可以将需要写入的值更改为您现在正在执行的操作。从整个选择的行范围隐式转换为数组,然后您使用
Join函数将该数组强制转换为字符串,以便可以将其写入 FSO 文件。那里的隐式转换将使用行中每个单元格的.Value。相反,您需要从单元格的.Text属性构建数组,我认为一次只能完成一个单元格/值。 -
@DavidZemens 大修是对的。查看答案。