简体   繁体   English

如何通过交叉方式复制数据?

[英]How to copy data by crossing way?

I need to copy values on a crossing way, as on the below pictures:我需要在交叉方式上复制值,如下图所示:
I arranged my data as two rows (with values) and then a one blank row and so on.我将数据排列为两行(带有值),然后是一个空白行,依此类推。
I tried the below code, but the output result is incorrect.我尝试了以下代码,但 output 结果不正确。
In advance, thanks for your help.预先感谢您的帮助。

Sub Copy_by_crossing()
 
  Dim ws As Worksheet, lastRow As Long, i As Long
 
  Set ws = ThisWorkbook.ActiveSheet
  lastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
 
  For i = 2 To lastRow
 
    If ws.Range("E" & i + 1).Value = "" Then
       ws.Range("E" & i + 1).Resize(, 4).Value = ws.Range("A" & i, "D" & i).Value
    End If
 
   Next i
 
End Sub

在此处输入图像描述

在此处输入图像描述

This seems to work:这似乎有效:

Option Explicit
Sub Copy_By_Crossing()
    Dim WS As Worksheet, rSrc As Range, rRes As Range
    Dim vSrc, vRes
    Dim I As Long, J As Long
    

'work in VBA arrays for faster execution times
    
Set WS = ThisWorkbook.Worksheets("Sheet1")
With WS
    Set rSrc = Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(columnsize:=4)
    vSrc = rSrc
    Set rRes = rSrc.Offset(0, UBound(vSrc, 2))
    ReDim vRes(1 To UBound(vSrc, 1), 1 To UBound(vSrc, 2))
End With

'create results array
'headers
For J = 1 To UBound(vSrc, 2)
    vRes(1, J) = vSrc(1, J)
Next J

'Reverse each pair of data
For I = 2 To UBound(vSrc, 1) Step 3
    For J = 1 To UBound(vSrc, 2)
        vRes(I + 1, J) = vSrc(I, J)
        vRes(I, J) = vSrc(I + 1, J)
    Next J
Next I
        
'Write back to the worksheet
With rRes
    .EntireColumn.Clear
    .Value = vRes
    .Style = "Output" 'This line may not work with non-english versions
    .EntireColumn.AutoFit
End With

End Sub

在此处输入图像描述

If you dispose of the newer dynamic features of MS 365 (esp. regarding the LET function), you might try the following formula alternative in cell E2 resulting in a spill range.如果您处理MS 365的较新动态功能(特别是关于LET函数),您可以在单元格E2中尝试以下公式替代,从而导致溢出范围。

The formulat itself defines 1, 2 or 0-indices and assigns different table areas to these indices via CHOOSE .该公式本身定义了 1、2 或 0 索引,并通过CHOOSE将不同的表区域分配给这些索引。

=LET(data,A2:A103,rep,3,cols,4,idx,IF(data & "" <>"",MOD(ROW(data)-1,rep),rep),CHOOSE(idx,OFFSET(data,1,,,cols),OFFSET(data,-1,,,cols),""))

The LET function allows to assign names to partial caluculation results within the function's arguments, thus avoiding a nested function with redundant calculations. LET function 允许为函数的 arguments 中的部分计算结果分配名称,从而避免嵌套的 function 进行冗余计算。

For better readibility here including line breaks:为了更好的可读性,包括换行符:

=LET(
    data,A2:A103,
    rep,3,
    cols,4,
    idx,IF(data & "" <>"",MOD(ROW(data)-1,rep),rep),
    CHOOSE(idx,OFFSET(data,1,,,cols),OFFSET(data,-1,,,cols),"")
    )

Side note : It might be interesting to experiment also with the partially not yet disponible functions ChooseCols and ChooseRows to slice & rearrange a given range by =CHOOSECOLS(CHOOSEROWS(A2:A3,{2,1}),{2,3,4}) applied extra upon each double row showing eg class, date & hr columns 2,3 & 4.旁注:尝试使用部分尚未分配的函数ChooseColsChooseRows来切片和重新排列给定范围可能很有趣=CHOOSECOLS(CHOOSEROWS(A2:A3,{2,1}),{2,3,4})在显示例如 class、日期和小时列 2、3 和 4 的每个双行上应用额外。

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

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