简体   繁体   English

使用VBA从列到行将Excel数据剪切和粘贴的自动化过程

[英]Automated Process to cut and paste excel data from columns to rows using VBA

I'm trying to create VBA code to cut and paste data from BCol1,BCol2,BCol3 into row directly beneath that record under ACol1,ACol2,ACol3. 我正在尝试创建VBA代码,以将BCol1,BCol2,BCol3中的数据剪切并粘贴到ACol1,ACol2,ACol3下该记录的正下方的行中。 Likewise for CCol1,CCol2,CCol3 and so on. 对于CCol1,CCol2,CCol3等也是如此。 Also I want common column data to be copied in first column for that specific record. 我也希望将公共列数据复制到该特定记录的第一列中。

I would like to create a code that loops for an entire set of data as I've 100+ columns, 10000+ rows and 50000+ Excel files to process data. 我想创建一个循环处理整个数据集的代码,因为我有100多个列,10000多个行和50000多个Excel文件来处理数据。 I need an automated solution. 我需要一个自动化的解决方案。

I can't open each Excel file and implement VBA code, so any pointer for that is also appreciated. 我无法打开每个Excel文件并实现VBA代码,因此对此的任何指针也将不胜感激。

This is how my sample data looks 这是我的样本数据的样子

这是我的样本数据的样子

This is how my sample data should look like 这就是我的样本数据的样子

这就是我的样本数据的样子

[Edit:] I've tried the following code: [编辑:]我尝试了以下代码:

Sub cut_paste()
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
LastColumn = Cells(1, Columns.Count).End(xlToLeft).Column

For i = lastRow To 2 Step -1
    Rows(i + 1).Insert
    Rows(i + 1).Insert
    Rows(i + 1).Insert
Next i

For j = 2 To 4 * (lastRow - 1) + 1 Step 4
    Range("E" & j).Select
    Selection.Cut
    Range("B" & j + 1).Select
    ActiveSheet.Paste
    Range("F" & j).Select
    Selection.Cut
    Range("C" & j + 1).Select
    ActiveSheet.Paste
    Range("G" & j).Select
    Selection.Cut
    Range("D" & j + 1).Select
    ActiveSheet.Paste

    Range("H" & j).Select
    Selection.Cut
    Range("B" & j + 2).Select
    ActiveSheet.Paste
    Range("I" & j).Select
    Selection.Cut
    Range("C" & j + 2).Select
    ActiveSheet.Paste
    Range("J" & j).Select
    Selection.Cut
    Range("D" & j + 2).Select
    ActiveSheet.Paste

    Range("K" & j).Select
    Selection.Cut
    Range("B" & j + 3).Select
    ActiveSheet.Paste
    Range("L" & j).Select
    Selection.Cut
    Range("C" & j + 3).Select
    ActiveSheet.Paste
    Range("M" & j).Select
    Selection.Cut
    Range("D" & j + 3).Select
    ActiveSheet.Paste
Next j

For k = 2 To 4 * (lastRow - 1) + 1 Step 4
    Range("A" & k).Select
    Selection.Copy
    For l = k + 1 To k + 3 Step 1
        Range("A" & l).Select
        ActiveSheet.Paste
    Next l
Next k
End Sub

I'm able to do this for sample data but for actual data its hectic task to do this way. 对于示例数据,我可以执行此操作,但对于实际数据,我可以执行此操作。

Thanks for any help! 谢谢你的帮助!

here is a vba procedure that you can adapt to your needs 这是一个vba程序,您可以适应您的需求

Sub aargh()
    sourcePath = "c:\sourcepath\"
    destpath = "c:\destpath\"
    f = Dir(sourcePath & "\*.xls*")
    While f <> "" 'loop tru all xls files in source directory
        Workbooks.Open (sourcePath & f) 
        lastrow = Cells(Rows.Count, "A").End(xlUp).Row
        lastcolumn = Cells(1, Columns.Count).End(xlToLeft).Column
        ' copy range to array a
        a = Range(Range("A1"), Cells(lastrow, lastcolumn))
        Cells.ClearContents
        For i = LBound(a, 1) + 1 To UBound(a, 1)
            For j = LBound(a, 2) + 1 To UBound(a, 2) Step 3
                li = li + 1
                Cells(li, 1) = a(i, LBound(a, 2))
                For k = 1 To 3
                    Cells(li, k + 1) = a(i, LBound(a, 2) + k + j - 2)
                Next k
            Next j
        Next i
        ' save modified file as new file
        ActiveWorkbook.SaveAs destpath & f
        f = Dir()
    Wend
End Sub

To do it a bit variable, you can use something like this: 为此,您可以使用如下所示的变量:

Option Explicit

Sub dada()
  Dim left_part As Long, split_part As Long, num_parts As Long, x, y

  x = Selection.Value2
  left_part = 1
  split_part = 3

  num_parts = (UBound(x, 2) - left_part) / split_part
  ReDim y(1 To num_parts * UBound(x), 1 To left_part + split_part)

  Dim i As Long, j As Long, k As Long, l As Long

  For i = 1 To UBound(x)
    For j = 1 To num_parts

      l = l + 1

      For k = 1 To left_part
        y(l, k) = x(i, k)
      Next

      For k = 1 To split_part
        y(l, k + left_part) = x(i, k + (j - 1) * split_part + left_part)
      Next

    Next
  Next

  Sheets.Add.Cells(2, 1).Resize(UBound(y), UBound(y, 2)) = y

End Sub

Just set left_part to the count of columns which will not be split. 只需将left_part设置为不会拆分的列数即可。 (in your example this is just common1, common2....) so if there are multiple columns then change that. (在您的示例中,这只是common1,common2 ....),因此,如果有多个列,则进行更改。 Also set split_part to the size of the parts to split. 还要将split_part设置为要分割的部分的大小。 (in your example this is 3 for *Col1, *Col2 and *Col3) ao if that differs, just change that to your needs. (在您的示例中,* Col1,* Col2和* Col3的值为3)。如果不同,则只需根据需要进行更改即可。

Now select your range to split without the upper headers (will be A2:M4 in your example) and run the macro. 现在,选择要拆分的范围而不包含上标头(在您的示例中为A2:M4),然后运行宏。

You also can set x to x = [A2:M4].Value2 or whatever you need if you do not want to select the range. 如果不想选择范围,也可以将x设置为x = [A2:M4].Value2或所需的任何值。

After splitting everything up, it will be pasted in a new sheet without formatting. 分割所有内容后,将其粘贴到新的工作表中而不进行格式化。 But having everything below each other should make it easy to to copy the formats to the columns as you need them (or after copying the date wherever you want it). 但是,将所有内容都放在另一个位置应该可以轻松地将格式复制到所需的列中(或在复制日期之后,在所需的位置)。

Just keep in mind to also copy the headers later on (as they seem to change in an unknown way, I've excluded them here) 请记住,稍后还要复制标头(由于标头似乎以未知的方式更改,因此我在此处将其排除在外)

If anything does not work as you want it or if you just have any questions, just ask ;) 如果任何事情都不如您所愿,或者您有任何疑问,请提出;)

hint: every interaction with the sheet will be MUCH slower then doing this just with variables. 提示:与工作表的每次交互都将比仅使用变量慢得多。 This way (for mid-ranged tables), executing this code and formatting it manually afterwards will be faster then copy/pasting via macro) 这样(对于中档表),执行此代码并随后对其进行手动格式化将比通过宏复制/粘贴更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM