处理一个单元格中的多个值以导出为CSV

我正在devise一个VBA脚本,将从Excel电子表格导出到CSV文件。 这将用于通过单独的Powershell脚本部署多个虚拟机。

目前,Export to CSV操作正在处理每个单元的单个虚拟机名称以及相应的设置,但是在脚本的实际执行过程中,我们可能会在一个单元中有多个虚拟机名称(用逗号分隔),但将具有相同的设置进行中的细胞。

我想知道的是,是否可以/如何去使那些由逗号分隔的单元格中的值填充单独的行,但是仍然具有CSV文件中相应标题下的设置。

代码:

Function BuildValuesString(colIndex As String, rows As String) As String Dim val As Variant For Each val In Split(rows, ",") If Cells(val, colIndex) <> "" Then BuildValuesString = BuildValuesString & Cells(val, colIndex).Value & "," Next val End Function Function BuildNullStrings(numNullStrings As Long) As String Dim iNullStrings As Long For iNullStrings = 1 To numNullStrings BuildNullStrings = BuildNullStrings & "" & "," Next iNullStrings End Function Sub WriteCSVFile2() Dim My_filenumber As Integer Dim logSTR As String My_filenumber = FreeFile logSTR = logSTR & "Srv. Descr." & "," logSTR = logSTR & "E-mail" & "," logSTR = logSTR & "Env." & "," logSTR = logSTR & "Prot. Level" & "," logSTR = logSTR & "DataC" & "," logSTR = logSTR & "# VMs" & "," logSTR = logSTR & "Name" & "," logSTR = logSTR & "Cluster" & "," logSTR = logSTR & "VLAN" & "," logSTR = logSTR & "NumCPU" & "," logSTR = logSTR & "MemoryGB" & "," logSTR = logSTR & "C_System" & "," logSTR = logSTR & "D_Homevg" & "," logSTR = logSTR & "App_eHealth" & "," logSTR = logSTR & "TotalDisk" & "," logSTR = logSTR & "Datastore" & "," logSTR = logSTR & "Template" & "," logSTR = logSTR & Chr(13) logSTR = logSTR & BuildValuesString("C", "18,19,20,21,22,26,27,28,29,30,31,32,33,34") logSTR = logSTR & TotalIt(Range("C32:C33")) logSTR = logSTR & Chr(13) logSTR = logSTR & BuildNullStrings(5) logSTR = logSTR & BuildValuesString("C", "18,19,20,21,22,37,38,39,40,41,42,43,44,46") logSTR = logSTR & TotalIt(Range("C43:C44")) logSTR = logSTR & Chr(13) logSTR = logSTR & BuildNullStrings(5) logSTR = logSTR & BuildValuesString("C", "18,19,20,21,22,48,49,50,51,52,53,54,55,58") logSTR = logSTR & TotalIt(Range("C54:C55")) Open "Z:\Operational Env. Requests\2016\Requests(Test)\" & ThisWorkbook.Name & ".csv" For Append As #My_filenumber Print #My_filenumber, logSTR Close #My_filenumber End Sub Function TotalIt(rng As Range) Dim c, arr, t, rv As Double, v For Each c In rng.Cells If Len(c.Value) > 0 Then arr = Split(c.Value, ",") For Each v In arr If IsNumeric(v) Then rv = rv + v Next v Exit For End If Next c TotalIt = rv End Function 

IE如果单元格C:27具有“VM1,VM2,VM3”,则分隔不同行上的每个值,但仍然input与其他标题相关的值。

目前VBA脚本将input值为:

 Name Cluster VLAN NumCPU MemoryGB VM1 VM2 VM3 VMCluster VLAN1 etc. 

我想要做的是

 Name Cluster VLAN VM1 VMCluster VLAN1 VM2 VMCluster VLAN1 VM3 VMCluster VLAN1 

如果我试图以当前的格式执行VBA脚本,它会完全调整alignment方式。 我希望得到一些帮助,以便我能够实现预期的结果。

感谢您提供的任何帮助

这太简单了,但是根据AC列中名称,群集和VLAN的简单示例,这将会把这个输出分成一个CSV文件。

 Sub SplitToCsv() Dim rw, lastRow As Long Dim ws As Worksheet Dim vms, vm, rowData As Variant Set ws = Sheets("Sheet1") lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row Open "C:\test.csv" For Output As #1 For rw = 1 To lastRow vms = Split(ws.Cells(rw, 1).Value2, ",") For Each vm In vms Print #1, Join(Array(vm, ws.Cells(rw, 2).Value2, ws.Cells(rw, 3).Value2), ",") Next vm Next rw Close #1 End Sub 

这将作为一个input:

 Name Cluster VLAN VM1,VM2,VM3 VMCluster VLAN1 VM4 VMCluster2 VLAN2 VM5,VM6 VMCluster3 VLAN3 

把它变成一个如下所示的文件:

 Name,Cluster,VLAN VM1,VMCluster,VLAN1 VM2,VMCluster,VLAN1 VM3,VMCluster,VLAN1 VM4,VMCluster2,VLAN2 VM5,VMCluster3,VLAN3 VM6,VMCluster3,VLAN3 

– 编辑1/3/2017 –

我想我现在明白了。 这是一个精简版/重构版本的代码。 我可能是错的,但我相信这是你想要做的:

 Sub WriteCSVFile2() Dim My_filenumber As Integer Dim header, line As String Dim values, vlan, names As Variant Dim row As Integer My_filenumber = FreeFile Open "c:\cdh\" & ThisWorkbook.Name & ".csv" For Append As #My_filenumber Print #My_filenumber, Join(Array("Srv. Descr.", "E-mail", "Env.", _ "Prot. Level", "DataC", "# VMs", "Name", "Cluster", "VLAN", _ "NumCPU", "MemoryGB", "C_System", "D_Homevg", "App_eHealth", _ "TotalDisk", "Datastore", "Template"), ",") header = Join(Application.Transpose(Range("C18:C22").Value), ",") For row = 26 To 50 Step 12 values = Application.Transpose(Range("C" & row & ":C" & row + 8).Value) names = values(2) For Each vlan In Split(names, ",") values(2) = vlan line = Join(values, ",") Print #My_filenumber, header & "," & line Next vlan Next row ' TotalIt(Range("C54:C55")) Close #My_filenumber End Sub 

一些注意事项: – 我注意到TotalIt只是因为我认为它的工作原理,并没有把重点放在那部分 – 你的代码看第TotalIt行,但电子表格实际上有引用TotalIt (一个额外的行)。 我的代码反映了后者

我认为如果你添加了更多的configuration选项,那么较小的代码库将更容易debugging,并希望更具可扩展性。

这是我的输出:

 Srv. Descr.,E-mail,Env.,Prot. Level,DataC,# VMs,Name,Cluster,VLAN,... Service,Email,Environment,Protection,Data Center,,VM1,VMCluster,VLAN1 etc.,,,,, Service,Email,Environment,Protection,Data Center,,VM2,VMCluster,VLAN1 etc.,,,,, Service,Email,Environment,Protection,Data Center,,VM3,VMCluster,VLAN1 etc.,,,,,