Excel 如果满足三种不同的条件,如何使用VBA将数据从一张图纸复制到另一张图纸?
我想使用VBA将满足一些条件的数据从一张图纸复制到另一张图纸 我的目标: 将工作表FP中E、F和G列中的单元格复制到工作表MUOR中的R、S和T列,如果它符合我的条件 我的条件: (1) D列中的单元格和p列中的单元格(在工作表MUOR中)必须满足工作表FP第I列中的条件 (2) 如果D列中的单元格为空,则跳到D列中的下一个单元格 (3) 粘贴前,列R、S或T必须为空。如果不为空,则移动到符合条件的下一个单元格。(请勿替换或复制数据) 其他信息:每天最大批号(D列)为3 面临的问题: 我当前的VBA代码无法识别我的状况。它完全忽略了我的第一天数据,并且复制了所有的第二天数据 请参考所附图片 单张纸 表FP 我的预期结果 我的当前代码如下:Excel 如果满足三种不同的条件,如何使用VBA将数据从一张图纸复制到另一张图纸?,excel,vba,Excel,Vba,我想使用VBA将满足一些条件的数据从一张图纸复制到另一张图纸 我的目标: 将工作表FP中E、F和G列中的单元格复制到工作表MUOR中的R、S和T列,如果它符合我的条件 我的条件: (1) D列中的单元格和p列中的单元格(在工作表MUOR中)必须满足工作表FP第I列中的条件 (2) 如果D列中的单元格为空,则跳到D列中的下一个单元格 (3) 粘贴前,列R、S或T必须为空。如果不为空,则移动到符合条件的下一个单元格。(请勿替换或复制数据) 其他信息:每天最大批号(D列)为3 面临的问题: 我当前的V
Sub LinkData()
Dim y As Long
Dim x As Long
Dim z As Long
Dim lr As Long
Dim arr As Variant
Dim FP As Worksheet
Dim MUOR As Worksheet
Set FP = ThisWorkbook.Sheets("FP")
Set MUOR = ThisWorkbook.Sheets("MUOR")
With FP
lr = .Cells(.Rows.Count, "A").End(xlUp).Row
arr = .Range("A1:I" & lr).Value
End With
With MUOR
For y = 11 To 363
For z = y - 1 To y + 8
For x = LBound(arr) To UBound(arr)
If Cells(11 + y, 4) <> "" And Cells(11 + y, 4) & Cells(10 + z, 16) = arr(x, 9) And IsEmpty(Cells(10 + z, 18)) Then
.Cells(10 + z, 18) = arr(x, 5)
.Cells(10 + z, 19) = arr(x, 8)
.Cells(10 + z, 20) = arr(x, 7)
Else
End If
Next x
Next z
Next y
End With
End Sub
子链接数据()
长得一样暗
暗x等长
暗z一样长
变暗lr为长
作为变体的Dim-arr
将FP设置为工作表
Dim MUOR As工作表
Set FP=ThisWorkbook.Sheets(“FP”)
Set MUOR=此工作簿.Sheets(“MUOR”)
与FP
lr=.Cells(.Rows.Count,“A”).End(xlUp).Row
arr=.Range(“A1:I”和lr).Value
以
与穆尔
对于y=11至363
对于z=y-1到y+8
对于x=LBound(arr)到UBound(arr)
如果单元格(11+y,4)”,以及单元格(11+y,4)和单元格(10+z,16)=arr(x,9)和等空(单元格(10+z,18)),则
.单元(10+z,18)=arr(x,5)
.单元(10+z,19)=arr(x,8)
.单元(10+z,20)=arr(x,7)
其他的
如果结束
下一个x
下一个z
下一个y
以
端接头
任何VBA专家请帮助我
非常感谢 我认为下面的代码应该给出预期的输出,但不能完全确定,因为上传/共享的工作簿似乎与问题中的屏幕截图不同
Option Explicit
Private Sub LinkData()
Dim arrayFromFPSheet() As Variant
arrayFromFPSheet = GetSourceArray()
Dim MUOR As Worksheet
Set MUOR = ThisWorkbook.Worksheets("MUOR")
Dim rangesToLoopThrough As Range
Set rangesToLoopThrough = GetDestinationAreas(MUOR)
With MUOR
Dim area As Range
For Each area In rangesToLoopThrough.Areas
Debug.Assert area.Rows.CountLarge > 1 And area.Rows.CountLarge < 20
Dim areaFirstRowIndex As Long
areaFirstRowIndex = area.Rows(1).Row
Dim areaLastRowIndex As Long
areaLastRowIndex = area.Rows(area.Rows.Count).Row
Dim readRowIndex As Long
For readRowIndex = areaFirstRowIndex To areaLastRowIndex
If Not IsCellEmpty(.Cells(readRowIndex, "D")) Then
Dim batchNumber As String
batchNumber = CStr(.Cells(readRowIndex, "D"))
Dim writeRowIndex As Long
For writeRowIndex = areaFirstRowIndex To areaLastRowIndex
If IsCellEmpty(.Cells(writeRowIndex, "R")) And IsCellEmpty(.Cells(writeRowIndex, "S")) And IsCellEmpty(.Cells(writeRowIndex, "T")) Then
Dim Grade As String
Grade = CStr(.Cells(writeRowIndex, "P"))
Dim batchNumberAndGrade As String
batchNumberAndGrade = batchNumber & Grade
Dim n As Variant
n = Application.CountIfs(.Range("P" & areaFirstRowIndex, "P" & writeRowIndex), Grade, .Range("R" & areaFirstRowIndex, "R" & writeRowIndex), batchNumber) + 1
Debug.Assert IsNumeric(n)
Dim sourceRowIndex As Long
sourceRowIndex = GetRowIndexOfNthMatch(n, arrayFromFPSheet, batchNumberAndGrade, 9)
If sourceRowIndex > 0 Then
.Cells(writeRowIndex, "R") = arrayFromFPSheet(sourceRowIndex, 5)
.Cells(writeRowIndex, "S") = arrayFromFPSheet(sourceRowIndex, 8)
.Cells(writeRowIndex, "T") = arrayFromFPSheet(sourceRowIndex, 7)
End If
End If
Next writeRowIndex
End If
Next readRowIndex
Next area
End With
End Sub
Private Function GetDestinationAreas(ByVal someSheet As Worksheet) As Range
' Crudely clusters/groups destination sheet into areas (which
' should be date-specific, although this function will not check/verify
' output).
Const START_ROW_INDEX As Long = 10
Dim outputRange As Range
Set outputRange = someSheet.Range("C" & START_ROW_INDEX, "C" & someSheet.Rows.Count)
On Error Resume Next
Set outputRange = outputRange.SpecialCells(xlCellTypeConstants) ' Will raise error if no constants found.
On Error GoTo 0
Debug.Assert Not (outputRange Is Nothing)
Set GetDestinationAreas = outputRange
End Function
Private Function GetSourceArray() As Variant
With ThisWorkbook.Worksheets("FP")
Dim lastRow As Long
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Dim outputArray() As Variant
outputArray = .Range("A1:I" & lastRow).Value
End With
GetSourceArray = outputArray
End Function
Private Function IsCellEmpty(ByVal someCell As Range) As Boolean
' https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/isempty-function
' "IsEmpty only returns meaningful information for variants."
' So using below function instead.
IsCellEmpty = Len(CStr(someCell.Value)) = 0
End Function
Private Function GetRowIndexOfNthMatch(ByVal n As Long, ByRef someArray() As Variant, ByVal someText As String, ByVal targetColumn As Long) As Long
' Returns a 1-based row index of the nth occurrence of text value
' in target column of array or 0 if unsuccessful.
Debug.Assert n > 0
Dim rowIndex As Long
For rowIndex = LBound(someArray, 1) To UBound(someArray, 1)
If someArray(rowIndex, targetColumn) = someText Then
Dim matchCount As Long
matchCount = matchCount + 1
If matchCount = n Then
GetRowIndexOfNthMatch = rowIndex
Exit Function
End If
End If
Next rowIndex
End Function
选项显式
专用子链接数据()
Dim arrayFromFPSheet()作为变量
arrayFromFPSheet=GetSourceArray()
Dim MUOR As工作表
Set MUOR=此工作簿。工作表(“MUOR”)
Dim Range(变暗范围)作为范围循环
设置rangesToLoopThrough=GetDestinationAreas(MUOR)
与穆尔
模糊区域作为范围
对于rangesToLoopThrough.Areas中的每个区域
Debug.Assert area.Rows.CountLarge>1和area.Rows.CountLarge<20
Dim AREA FIRSTROWINDEX尽可能长
areaFirstRowIndex=area.Rows(1.Row)
Dim AREA LASTROWINDEX尽可能长
areaLastRowIndex=area.Rows(area.Rows.Count).Row
Dim readRowIndex尽可能长
对于readRowIndex=areaFirstRowIndex到areaLastRowIndex
如果不是IsCellEmpty(.Cells(readRowIndex,“D”)),则
Dim batchNumber作为字符串
batchNumber=CStr(.Cells(readRowIndex,“D”))
Dim WRITEROVINDEX尽可能长
对于writeRowIndex=areaFirstRowIndex到areaLastRowIndex
如果是IsCellEmpty(.Cells(writeRowIndex,“R”)、IsCellEmpty(.Cells(writeRowIndex,“S”)、IsCellEmpty(.Cells(writeRowIndex,“T”)),则
将等级设置为字符串
等级=CStr(.Cells(writeRowIndex,“P”))
Dim BatchNumber和Grade作为字符串
batchNumber和等级=batchNumber和等级
作为变体的dimn
n=Application.CountIfs(.Range(“P”和areaFirstRowIndex,“P”和writeRowIndex)、Grade、.Range(“R”和areaFirstRowIndex、“R”和writeRowIndex)、批次号)+1
Debug.Assert是数字(n)
Dim sourceRowIndex尽可能长
sourceRowIndex=GetRowIndexOfNthMatch(n,来自FPSheet的数组,批次号和等级,9)
如果sourceRowIndex>0,则
.Cells(writeRowIndex,“R”)=来自fpsheet的数组(sourceRowIndex,5)
.Cells(writeRowIndex,“S”)=来自fpsheet的数组(sourceRowIndex,8)
.Cells(writeRowIndex,“T”)=来自fpsheet的数组(sourceRowIndex,7)
如果结束
如果结束
下一个writeRowIndex
如果结束
下一个readRowIndex
下一个领域
以
端接头
私有函数GetDestinationAreas(ByVal someSheet作为工作表)作为范围
'将目标工作表粗略地聚集/分组到区域(其中
'应该是特定于日期的,尽管此函数不会检查/验证
"输出)。
Const START_ROW_索引长度=10
Dim outputRange As范围
Set outputRange=someSheet.Range(“C”和开始行索引,“C”和someSheet.Rows.Count)
出错时继续下一步
如果找不到常量,Set-outputRange=outputRange.SpecialCells(xlCellTypeConstants)”将引发错误。
错误转到0
不断言(outputRange为Nothing)
设置GetDestinationAreas=outputRange
端函数
私有函数GetSourceArray()作为变量
使用此工作簿。工作表(“FP”)
最后一排一样长
lastRow=.Cells(.Rows.Count,“A”).End(xlUp).Row
Dim outputArray()作为变量
outputArray=.Range(“A1:I”和lastRow).Value
以
GetSourceArray=outputArray
端函数
私有函数是布尔型的Ellempty(ByVal someCell作为范围)
' https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/isempty-function
“IsEmpty仅返回变量的有意义信息。”
'所以改用下面的函数。
IsCellEmpty=Len(CStr(someCell.Value))=0
端函数
私有函数getRowIndexOfntMatch(ByVal n为Long,ByRef someArray()为Variant,ByVal someText为String,ByVal targetColumn为Long)为Lon