在一个单元格中处理多个值以导出为CSV [英] Handling Multiple Values in One Cell to Export To CSV

查看:57
本文介绍了在一个单元格中处理多个值以导出为CSV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设计一个VBA脚本,该脚本会将值从Excel电子表格导出到CSV文件.这将用于通过单独的Powershell脚本部署多个虚拟机.

I am trying to design a VBA script that will export values from an Excel spreadsheet to a CSV file. This will be used for deployment of multiple Virtual Machines by a separate Powershell script.

当前,导出到CSV"操作正在每个单元格处理一个虚拟机名称以及相应的设置,但是,在脚本的实际执行中,我们可能在单个单元格中有多个虚拟机名称(以逗号分隔),但是将具有程序单元格中的设置相同.

Currently the Export to CSV operation is handling one single VM name per cell and the corresponding settings however, in the actual execution of the script we may have multiple VM names in a single cell (separated by a comma) but will have the same settings in the proceeding cells.

我想知道的是,是否有可能/如何在该单元格中将那些用逗号分隔的值填充到单独的行中,但仍在CSV文件中的适当标题下进行设置.

What I would like to know is whether it is possible/how to go about having those values in that cell that are separated by a comma populate a separate line but still have the settings under the appropriate headings within the CSV file.

代码:

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

I.E. 如果单元格C:27具有"VM1,VM2,VM3",请在不同的行上分隔每个值,但仍输入与其他标头关联的值.

I.E. If cell C:27 has "VM1, VM2, VM3", separate each value on a different line but still input values associated with the other headers.

当前,VBA脚本会将值输入为:

Currently the VBA script would input the values as:

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

我想做的是

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

如果我尝试以当前格式执行VBA脚本,它将完全弄乱对齐方式.我希望能获得一些帮助,以实现理想的结果.

It messes up the alignment completely if I attempt to execute the VBA script in its current format. I was hoping to get some help on how I could go about achieving the desired results.

感谢您提供的任何帮助

推荐答案

这在根本上是过分简化的,但是根据您在AC列中的名称",集群"和"VLAN"的简化示例,可以采用这种方法并将输出拆分为CSV.

This is radically oversimplified, but based on your simplified example of Name, Cluster and VLAN in columns A-C, this would take that and split the output to a 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

这将作为输入:

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

并将其转换为如下所示的文件:

And turn it into a file that looks like this:

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

-编辑1/3/2017-

-- EDIT 1/3/2017 --

我想我明白了.这是代码的精简版/重构版.我可能是错的,但是我相信,这就是您要执行的操作:

I think I get it now. This is a slimmed-down / refactored version of your code. I could be wrong, but I believe this is what you're trying to do:

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注释掉只是因为我认为它可以正常工作,而不是专注于该部分 -您的代码查看了第26、37、48行,但电子表格实际上在26、38、50处有引用(另外一行).我的代码反映了后者

Some notes: - I commented out TotalIt just because I assume it works and wasn't focused on that part - Your code looked at rows 26, 37, 48 but the spreadsheet actually had the references at 26, 38, 50 (one additional row). My code reflects the latter

我认为,如果您添加更多配置选项,则较小的代码库将更易于调试,并希望具有更高的可扩展性.

I think the smaller code base will be easier to debug and hopefully more scalable, if you ever add more config options.

这是我的输出:

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.,,,,,

这篇关于在一个单元格中处理多个值以导出为CSV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆