我有要移入模板的数据,并且正在尝试重新利用我使用的vba脚本。以前,需要将数据转置到特定范围内,但是现在我希望将其移出而无需进行转置。
'Write the employee data into the template
a = 0
For k = 2 To UBound(Data, 2)
Dest.Offset(a, j) = Data(i, k)
a = a + 1
Next
我假设dest.offset
属性是引起转置的原因,我如何将其更改为仅在不进行转置的情况下正常移动数组?
其他脚本:
Option Explicit
Sub Main()
Dim Wb As Workbook
Dim Data, Last
Dim i As Long, j As Long, k As Long, a As Long
Dim Dest As Range
'Refer to the template
Set Wb = Workbooks("ValidationTemplate.xlsx")
'Refer to the destination cell
Set Dest = Wb.Sheets("Employee Core Skills").Range("B3")
'Read in all data
With ThisWorkbook.Sheets("Sheet1")
Data = .Range("DO2", .Range("A" & Rows.Count).End(xlUp))
End With
Wb.Activate
Application.ScreenUpdating = False
'Process the data
For i = 1 To UBound(Data)
'Manager changes?
If Data(i, 1) <> Last Then
'Skip the first
If i > 1 Then
'Scroll into the view
Dest.Select
'Save a copy
Wb.SaveCopyAs ThisWorkbook.Path & Application.PathSeparator & _
ValidFileName(Last & "_Assessment.xlsx")
End If
'Clear the employees
Dest.Resize(, Columns.Count - Dest.Column).EntireColumn.ClearContents
'Remember this manager
Last = Data(i, 1)
'Start the next round
j = 0
End If
'Write the employee data into the template
a = 0
For k = 2 To UBound(Data, 2)
Dest.Offset(a, j) = Data(i, k)
a = a + 1
Next
End If
'Next column
j = j + 1
Next
End Sub
答案 0 :(得分:3)
如果我正确理解了您的问题...
Dest.Offset(a, j)
表示使用Range
所指的Range Object
的{{1}},然后从那里Dest
行偏移(正数在电子表格的下方,负数在电子表格的上方)和a
列(在右侧为正,在左侧为负)。
如果您只想将数据放入j
指向的Range
中,则只需省略Dest
部分,就像这样:
.Offset()
注意:Dest.value2 = Data(i,k).value2
是您仅通过引用.Value
而忽略的默认成员。始终最好指定而不是让VBA弄清楚您的意思。为什么要使用Dest
而不是.Value2
?阅读此SO question and the accepted answer。
由于.Value
和a
的顺序,转置在这里发生。
j
由于不清楚变量名,很难说出来。
如果您这样重命名变量:
a = 0
For k = 2 To UBound(Data, 2)
Dest.Offset(a, j) = Data(i, k)
a = a + 1
Next
End If
'Next column
j = j + 1
您将看到它们正在被使用,并且您想要做的是将Dim I as Long --> Dim sourceRow as Long
Dim K as Long --> Dim sourceCol as Long
Dim A as Long --> Dim destRow as Long
Dim J as Long --> Dim destCol as Long
与destRow
交换。
使用新的变量名重写该代码将为您提供:
destCol
,现在您可以更容易地看到循环使您的destRow = 0
For sourceCol = 2 To UBound(Data, 2)
Dest.Offset(destRow, destCol) = Data(sourceRow, sourceCol)
destRow = destRow + 1
Next
End If
'Next column
destCol = destCol + 1
和sourceCol
递增。如果您现在将其更改为:
destRow
您将看到循环现在同时增加了source和dest列。现在,您只需要在外循环中更改增量器来同步更新行,就可以了。
这是一个很棒的对象课程,它说明了为什么代码“物”的好名字非常有价值。一旦我整理出destRow = 0
For sourceCol = 2 To UBound(Data, 2)
Dest.Offset(destRow, destCol).Value2 = Data(sourceRow, sourceCol).Value2
destCol = destCol + 1
Next
End If
'Next column
destRow = destRow + 1
,a
,i
和j
,就很明显了。看来您不是该代码的原始作者,但是即使您是肯定的,也可以。我们大多数人一开始都是用可怕的名字来命名,然后随着时间的推移慢慢学习好名字的价值。重构代码以改进这些名称和其他名称非常值得。
VBE的Rubberduck plugin的快速无耻插头。我是一个狂热的粉丝,也开始为这个项目做贡献。它将允许您通过智能地重命名变量来重构代码。您可以想象,搜索并替换k
到i
将会sourceRow
将sourceRow
带给您一些严重损坏的代码sourceRow
! Rubberduck可以避免该问题,并添加许多很多其他功能,您很快就会想知道如果没有这些功能,生活会如何!