Excel 如果满足三种不同的条件,如何使用VBA将数据从一张图纸复制到另一张图纸?

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

我想使用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

我的预期结果

我的当前代码如下:

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