我有一个.csv文件(还有很多类似的文件),它们组织得不好。这是一个示例文件
Number,A1Name,A1DoVote,A1Vote,A2Name,A2DoVote,A2Vote,A3Name,A3DoVote,A3Vote,Solution
1,One,true,0,Two,false,50,Three,true,100,50.0
2,One,true,0,Two,false,50,Three,true,100,50.0
3,Two,true,100,One,true,0,Three,false,100,50.0
4,Two,true,100,One,true,0,Three,false,100,50.0
5,Three,true,100,One,true,0,Two,false,50,50.0
6,Three,false,100,One,true,0,Two,true,100,50.0
7,Three,true,100,One,true,0,Two,false,50,50.0
8,Three,false,100,One,true,0,Two,true,100,50.0
9,Two,false,50,Three,true,100,One,true,0,50.0
10,Two,true,100,Three,false,100,One,true,0,50.0
11,Three,true,100,Two,false,50,One,true,0,50.0
12,Three,false,100,Two,true,100,One,true,0,50.0
我在Excel中导入了它,但问题是我需要按名称来组织数据,因此“一个”,“两个”,“三个”而不是行数。是否有一种很好的方法来使数据始终始终显示“一个”,并在右侧显示与之相邻的两列,然后再显示“两个”,然后再显示“三”(再次与相邻的两个列一起显示? 这些行是数据集,因此它们需要保持这种状态,我只想在列之间进行切换。
如果不清楚,请评论,我会尽快修复。
这是上面.csv代码在Excel中的样子
这就是我想要的:
如您所见,“一”,“二”和“三”都在同一列中,并且两个右手边的值仍与它们相邻。 (Wahr是正确的,而falsch是错误的)
答案 0 :(得分:0)
您应该发现这可行。所有范围等都是动态确定的,因此这将适用于长数据文件或短数据文件。数据被临时复制到数据范围的右侧(M至U列),然后剪切并复制回去。
Sub VoteSortbyRow()
Dim lRow As Long, lCol As Long
Dim LR As Long, a1data As Long, a2data As Long, a3data As Long
Dim a1name As Long, a2name As Long, a3name As Long
Dim namecount As Long
' assign a value for the number of voyter name columns
namecount = 3
' assign column number for left hand column of the three name ranges
a1name = 2
a2name = 5
a3name = 8
' assign column number for left hand column of the three temporary data ranges (out to the right of the data)
a1data = 13
a2data = 16
a3data = 19
' get the active sheet name
MySheet = ActiveSheet.Name
'Find the last non-blank cell in column B
LR = Cells(Rows.Count, 2).End(xlUp).Row
' Select cell B2
Cells(2, 2).Select
For a1loop_ctr = 2 To LR
'Statements to be executed inside the loop
' evaluate column B for value = One, Two or Three; copy data across to respective data ramge on the same row.
If Cells(a1loop_ctr, a1name) Like "One" Then
ActiveSheet.Range(Cells(a1loop_ctr, a1name), Cells(a1loop_ctr, (a1name + 2))).Copy Destination:=Cells(a1loop_ctr, a1data)
ElseIf Cells(a1loop_ctr, a1name) Like "Two" Then
ActiveSheet.Range(Cells(a1loop_ctr, a1name), Cells(a1loop_ctr, (a1name + 2))).Copy Destination:=Cells(a1loop_ctr, a2data)
ElseIf Cells(a1loop_ctr, a1name) Like "Three" Then
ActiveSheet.Range(Cells(a1loop_ctr, a1name), Cells(a1loop_ctr, (a1name + 2))).Copy Destination:=Cells(a1loop_ctr, a3data)
Else
'Error message and exist in case the cell is invalid
MsgBox "VALIDATION ERROR: Cell " & Replace(Replace(Cells(1, a1name).Address, "1", ""), "$", "") & a1loop_ctr & " does not contain a valid voter Name"
Exit Sub
End If
Next a1loop_ctr
For a2loop_ctr = 2 To LR
'Statements to be executed inside the loop
' evaluate column E for value = One, Two or Three; copy data across to respective data ramge on the same row.
If Cells(a2loop_ctr, a2name) Like "One" Then
ActiveSheet.Range(Cells(a2loop_ctr, a2name), Cells(a2loop_ctr, (a2name + 2))).Copy Destination:=Cells(a2loop_ctr, a1data)
ElseIf Cells(a2loop_ctr, a2name) Like "Two" Then
ActiveSheet.Range(Cells(a2loop_ctr, a2name), Cells(a2loop_ctr, (a2name + 2))).Copy Destination:=Cells(a2loop_ctr, a2data)
ElseIf Cells(a2loop_ctr, a2name) Like "Three" Then
ActiveSheet.Range(Cells(a2loop_ctr, a2name), Cells(a2loop_ctr, (a2name + 2))).Copy Destination:=Cells(a2loop_ctr, a3data)
Else
'Error message and exist in case the cell is invalid
MsgBox "VALIDATION ERROR: Cell " & Replace(Replace(Cells(1, a2name).Address, "1", ""), "$", "") & a2loop_ctr & " does not contain a valid voter Name"
Exit Sub
End If
Next a2loop_ctr
For a3loop_ctr = 2 To LR
'Statements to be executed inside the loop
' evaluate column H for value = One, Two or Three; copy data across to respective data ramge on the same row.
If Cells(a3loop_ctr, a3name) Like "One" Then
ActiveSheet.Range(Cells(a3loop_ctr, a3name), Cells(a3loop_ctr, (a3name + 2))).Copy Destination:=Cells(a3loop_ctr, a1data)
ElseIf Cells(a3loop_ctr, a3name) Like "Two" Then
ActiveSheet.Range(Cells(a3loop_ctr, a3name), Cells(a3loop_ctr, (a3name + 2))).Copy Destination:=Cells(a3loop_ctr, a2data)
ElseIf Cells(a3loop_ctr, a3name) Like "Three" Then
ActiveSheet.Range(Cells(a3loop_ctr, a3name), Cells(a3loop_ctr, (a3name + 2))).Copy Destination:=Cells(a3loop_ctr, a3data)
Else
'Error message and exist in case the cell is invalid
MsgBox "VALIDATION ERROR: Cell " & Replace(Replace(Cells(1, a3name).Address, "1", ""), "$", "") & a3loop_ctr & " does not contain a valid voter Name"
Exit Sub
End If
Next a3loop_ctr
' cut the data for One and paste it to column B
ActiveSheet.Range(Cells(2, a1data), Cells(LR, a1data + 2)).Cut Destination:=Cells(2, a1name)
' cut the data for TWO and paste it to column E
ActiveSheet.Range(Cells(2, a2data), Cells(LR, a2data + 2)).Cut Destination:=Cells(2, a2name)
' cut the data for THREE and paste it to column H
ActiveSheet.Range(Cells(2, a3data), Cells(LR, a3data + 2)).Cut Destination:=Cells(2, a3name)
' Select cell B2
Cells(2, 2).Select
End Sub
如何添加一名额外的选民
如果添加第5,第6选民,则遵循相同的方法。
如果您有很多文件,那么您可能还会发现此宏很方便。它使您可以浏览csv文件,打开文件,将数据插入工作表,然后将工作表重命名为文件名。
Sub ImportCSVVoting()
Dim vPath As Variant
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Set wb = Excel.ActiveWorkbook
Set ws = Excel.ActiveSheet
vPath = Application.GetOpenFilename("CSV (Comma Delimited) (*.csv),*.csv" _
, 1, "Select a file", , False)
''//Show the file open dialog to allow user to select a CSV file
If vPath = False Then Exit Sub
''//Exit macro if no file selected
Workbooks.OpenText Filename:=vPath, Origin:=xlMSDOS, StartRow:=1 _
, DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, Comma:=True _
, FieldInfo:=Array(Array(1, xlTextFormat), Array(2, xlTextFormat), _
Array(3, xlTextFormat))
''//The fieldinfo array needs to be extended to match your number of columns
Columns.EntireColumn.AutoFit
''//Resize the columns
Sheets(1).Move Before:=wb.Sheets(1)
''//Move the data into the Workbook
Cells(1, 1).Select
''// Select cell A1
End Sub
答案 1 :(得分:0)
如果尚未拆分单元格,请在选择单元格的情况下运行此宏...我复制并粘贴了您所拥有的内容并进行了处理。
如果您已经将它们作为CSV导入到excel中并将其值拆分为自己的列,则还有其他一些方法。这有帮助吗? VBA中确实有很多解决此类问题的方法。
Sub SplitOneTwoThree()
Dim Arr1 As Variant
Dim I as long
Dim K As long
For I = 1 To Selection.Rows.Count
Arr1 = Split(ActiveCell.Offset(I - 1, 0).Value, ",")
For K = 1 To UBound(Arr1)
If Arr1(K) = "One" Then
ActiveCell.Offset(I - 1, 1) = Arr1(K)
ActiveCell.Offset(I - 1, 2) = Arr1(K + 1)
ActiveCell.Offset(I - 1, 3) = Arr1(K + 2)
K = K + 2
End If
If Arr1(K) = "Two" Then
ActiveCell.Offset(I - 1, 4) = Arr1(K)
ActiveCell.Offset(I - 1, 5) = Arr1(K + 1)
ActiveCell.Offset(I - 1, 6) = Arr1(K + 2)
K = K + 2
End If
If Arr1(K) = "Three" Then
ActiveCell.Offset(I - 1, 7) = Arr1(K)
ActiveCell.Offset(I - 1, 8) = Arr1(K + 1)
ActiveCell.Offset(I - 1, 9) = Arr1(K + 2)
K = K + 2
End If
Next K
Next I
End Sub
答案 2 :(得分:0)
下面的代码并不漂亮,但是它可以满足您的要求,包括Solution值。将“ Sheet1”更改为数据所在的工作表。
Set ws = Worksheets("Sheet1")
lRow = ws.Cells(Rows.Count, 2).End(xlUp).Row
Set rng = ws.Range("B2:B" & lRow)
Dim x As Long
Dim i As Long
For i = 1 To 2
For x = 2 To lRow
If Cells(x, "B").Value <> "One" Then
Cells(x, "B").Resize(, 3).Copy
Cells(x, "B").Offset(, 9).Insert Shift:=xlToRight
Cells(x, "B").Resize(, 3).Delete Shift:=xlToLeft
End If
Next
Next i
For x = 2 To lRow
If Cells(x, "E").Value <> "Two" Then
Cells(x, "E").Resize(, 3).Copy
Cells(x, "E").Offset(, 6).Insert Shift:=xlToRight
Cells(x, "E").Resize(, 3).Delete Shift:=xlToLeft
End If
Next