【问题标题】:Moving cell data into different worksheets将单元格数据移动到不同的工作表中
【发布时间】:2021-07-08 09:38:45
【问题描述】:

我确信这是我正在犯的一个相当简单的错误,但我正在努力弄清楚将东西放入的顺序。

我有一组数据位于一个工作表中,我想将某些数据单元格移动到其他工作表(“成本 1”到“成本 5”)。

我在 Excel 中使用公式(唯一和计数)来计算应将多少行数据移动到每个工作表中,这在 S 列 (ProdNum) 中。

我在 Cell V3 中也有一个帐户总数。理想情况下,代码应该只循环这么多次(即总帐户=要复制到的工作表总数)- 5 是最大值,但它可能低至 1。我只能谷歌/想到将数组从 LBound 循环到UBound 所以它现在一直在循环......不过目前这没什么大不了的。

最大的问题是所有数据都将进入所有工作表 - 在移动到下一个工作表之前,它不会停留在我希望它停止的行数。

这是数据示例

Row number Column J... Column S...
... ... ...
5 Product name 1 1
6 Product name 2 3
7 Product name 3 1
8 Product name 4 1
9 Product name 5 1
10 Product name 6 1
11 Product name 7 1

在本例中,产品名称 1 到 7 将出现在所有 5 个“成本”工作表中。

而我想要发生的是:

  • 产品名称 1 应出现在(工作表:)成本 1 中,
  • 产品名称 2 - 4 应出现在成本 2 中
  • 产品名称 5 应出现在成本 3 中
  • 产品名称 6 应出现在成本 4 中
  • 产品名称 7 应出现在成本 5 中

谁能帮帮我?此外,如果您认为代码通过循环浏览 5 个工作表而超时工作,那么我也非常感谢那里的一些帮助。

谢谢。

编辑:

我稍微编辑了代码以删除干扰问题的 msgbox,并且我在中途使用了不正确的变量(从 status_1 更改为 TotalAcc。

进一步补充这一点以及我期望它做的事情:

Option Explicit
Sub startdata()
    
    Dim i                   As Long
    Dim a                   As Long
    Dim ProdNum             As Long
    
    Dim prod                As Long
    Dim prod1               As Long
    
    Dim Transaction         As Double
    Dim Incidental          As Double
    Dim Weighting           As Double
    
    Dim ws                  As Worksheet
    Dim ProdName            As String
    Dim TotalAcc            As String
    Dim InxW                As Long
    Dim WshtNames           As Variant
    
    
    WshtNames = Array("Costs 1", "Costs 2", "Costs 3", "Costs 4", "Costs 5")
    
    Set ws = ThisWorkbook.Worksheets("Data")
    
    With ws
        
        TotalAcc = .Cells(3, 22).Value
    
            ProdNum = 5
'The next bit of code I would hope is going to start off the loop of setting the number of times it needs to loop (starting at 5, to TotalAcc (which is a number no higher than 5) + 5. So in other words from '5 to 10 '.
            For ProdNum = 5 To TotalAcc+ 5
'I'm now telling it to loop through each of the worksheets as set above in my worksheet array.
                For InxW = LBound(WshtNames) To UBound(WshtNames)
'So it knows which cell to copy across I have set "prod" to the value of the loop of ProdNum - i.e. starting at 5,19 (in the example table above this would have a value of 1). On the next loop though, I am expecting the row '5' (i.e. ProdNum) to turn to a 6. This would give me a value of 3 - as per the table above.
               
                prod = .Cells(ProdNum, 19).Value
'The data actually lives on cells starting at row 3. So, to start the loop of the potentially multiple sets of data to be copied, I have told it to start at 3 and finish at prod (currently "1") + 2. So my example above, the data would first start at 3 and finish at 3.
'On the next loop I now have a Prod = 3 therefore I would expect i (which is now 4) to loop from 4 through to 6..... hold up! I think I'm going wrong here...."i" will grow from 3 to 4, but "prod" might not be high enough, i need to add a cumulative prodnumber to the loop not just the absolute amount for that account...          
                For i = 3 To prod + 2
                    
                    ProdName= .Cells(i, 10).Value
                    Transaction = .Cells(i, 14).Value
                    Weighting = .Cells(i, 12).Value
                    
                    With Worksheets(WshtNames(InxW))
                        .Cells(i + 1, 2).Value = ProdName
                        .Cells(i + 1, 6).Value = Transaction
                        .Cells(i + 1, 5).Value = Weighting
                    End With
                    
                Next i
                
            Next InxW
            
        Next ProdNum
    End With
    

End Sub

已编辑:

我已对其进行了更改,现在它正在查看累积的下一组单元格(从 ProdNum,20 开始),我还破解了有关将相同数据推送到每个成本选项卡中的问题。 (但添加一个 ProdNum + 1 和一个新的 inum 变量 - 并在每个循环后添加 1)。

我快到了...但是,因为我将“i”作为获取数据的变量以及将数据放在哪里 - 单元格引用现在从“成本”选项卡中的错误点开始。换句话说,我的成本选项卡 1 从第 3 行开始。当它根据上表获取一位数据时,它会移动到下一个循环(太棒了!) - 下一个循环从数据选项卡中的第 4 行开始 - 但是将其写入第 4 行以及成本 2 选项卡中。是否可以同时运行 2 个循环(例如,如果我重命名此代码的一侧):

                sh.Cells(i + 1, 2).Value = ws.Cells(i, 10).Value        'ProdName
                sh.Cells(i + 1, 6).Value = ws.Cells(i, 14).Value        'Transaction
                sh.Cells(i + 1, 5).Value = ws.Cells(i, 12).Value        'Weighting

这是目前为止的新代码:


    Option Explicit

Sub startdata()
    Dim i           As Long, ProdNum As Long, prod As Long, TotalAcc As Long, inum As Long
    Dim ws          As Worksheet, sh As Worksheet, mtch, WshtNames As Variant
    
WshtNames = Array("Costs 1", "Costs 2", "Costs 3", "Costs 4", "Costs 5")
    Set ws = ThisWorkbook.Worksheets("Data")
    TotalAcc = ws.Cells(3, 22).Value
    If TotalAcc = 0 Then MsgBox "Nothing has been imported, please try importing again.", vbCritical: Exit Sub
    ProdNum = 5
    inum = 5
    
    
    For Each sh In ThisWorkbook.Sheets
        mtch = Application.Match(sh.Name, WshtNames, 0)
        If sh.Name <> ws.Name And Not IsError(mtch) Then
            prod = ws.Cells(ProdNum, 20).Value
            'in cells(inum, 21) and the rows below are the starting points for where I want "i" to look at. In other words, it always starts at 3 (for row 3), and then the row below gets added by the number of rows for the next set. In this case the first set is 1, and the second set is 3 - therefore inum starts off at 3, on the second loop = 4, and the third loop = 7.           
            i = ws.Cells(inum, 21).Value
            For i = i To prod + 2
                sh.Cells(i + 1, 2).Value = ws.Cells(i, 10).Value        'ProdName
                sh.Cells(i + 1, 6).Value = ws.Cells(i, 14).Value        'Transaction
                sh.Cells(i + 1, 5).Value = ws.Cells(i, 12).Value        'Weighting
            Next i
            ProdNum = ProdNum + 1
            inum = inum + 1
            
        End If
    Next
    
End Sub

最后的编辑 - 我在最后的地方有点慢,以确保为代码的目标部分写入正确的单元格。

但这里是:


    Option Explicit

Sub startdata()
    Dim i           As Long, b As Long, ProdNum As Long, prod As Long, TotalAcc As Long, inum As Long
    Dim ws          As Worksheet, sh As Worksheet, mtch, WshtNames As Variant
    
WshtNames = Array("Costs 1", "Costs 2", "Costs 3", "Costs 4", "Costs 5")
    Set ws = ThisWorkbook.Worksheets("Data")
    TotalAcc = ws.Cells(3, 22).Value
    If TotalAcc = 0 Then MsgBox "Nothing has been imported, please try importing again.", vbCritical: Exit Sub
    ProdNum = 5
    inum = 5
    
    'For ProdNum = 5 To TotalAcc + 5 'this loop does not influence what is coming. It looks useless...
    
    For Each sh In ThisWorkbook.Sheets
        mtch = Application.Match(sh.Name, WshtNames, 0)
        If sh.Name <> ws.Name And Not IsError(mtch) Then
            prod = ws.Cells(ProdNum, 20).Value
'in cells(inum, 21) and the rows below are the starting points for where I want "i" to look at. In other words, it always starts at 3 (for row 3), and then the row below gets added by the number of rows for the next set. In this case the first set is 1, and the second set is 3 - therefore inum starts off at 3, on the second loop = 4, and the third loop = 7.    
            i = ws.Cells(inum, 21).Value
            b = 3

            For i = i To prod + 2
      
            
                sh.Cells(b + 1, 2).Value = ws.Cells(i, 10).Value        'ProdName
                sh.Cells(b + 1, 6).Value = ws.Cells(i, 14).Value        'Transaction
                sh.Cells(b + 1, 5).Value = ws.Cells(i, 12).Value        'Weighting

                b = b + 1
            Next i

            
            ProdNum = ProdNum + 1
            inum = inum + 1
            
        End If
    Next
    
End Sub

【问题讨论】:

  • 确保你使用了Option Explicit,你的一些变量没有像status_1那样声明。请edit您的问题添加如何确定哪个产品去哪里?目前还不清楚您想要哪种结果以及如何到达那里。
  • @Pᴇʜ 好的,谢谢 - 我已对代码进行了注释以使其更清晰,并删除了一些令人困惑的多余部分。 status_1 是错误留下的,应该是 TotalAcc。当我评论时,我认为我发现了一个错误,我是否走在正确的道路上?
  • 请解释(用文字)你想在For ProdNum = 5 To status_1 + 5开始的循环中做什么。
  • @FaneDuru 我认为自从您编写此代码以来,我已经编辑了代码。 status_1 已被 TotalAcc 替换。如果还不清楚,请告诉我,我会再试一次!
  • 因为 ProdNum 从未在其循环中使用,这就是它的含义。如果TotalAcc 大于零,则循环` For i = 3 To prod + 2` 将做同样的事情,但次数更多。我想你对它有不同的期望,我想听听它是什么......

标签: arrays excel vba loops


【解决方案1】:

请测试下一个代码。它更紧凑,它应该做你需要的(我理解)。不需要这么多变量,这只是为了混淆试图理解代码的人。它包含一个无用的循环(已评论),我在上面的评论中要求澄清,但我保留了它......

Sub startdata()
    Dim i  As Long, ProdNum As Long, prod As Long, status_1 As Long, TotalAcc As Long
    Dim ws As Worksheet, sh As Worksheet, mtch, WshtNames As Variant, inum As Long
       
    WshtNames = Array("Costs 1", "Costs 2", "Costs 3", "Costs 4", "Costs 5")
    Set ws = ThisWorkbook.Worksheets("Data")
    TotalAcc = ws.cells(3, 22).value
    If TotalAcc = 0 Then MsgBox "Nothing has been imported, please try importing again.", vbCritical: Exit Sub
    ProdNum = 5: inum = 5
    
    For Each sh In ThisWorkbook.Sheets
        mtch = Application.match(sh.Name, WshtNames, 0)
            If sh.Name <> ws.Name And Not IsError(mtch) Then                 
                 For ProdNum = 5 To TotalAcc + 5 'this loop does not influence what is coming. It looks useless...
                    prod = ws.cells(ProdNum, 19).value
                    i = ws.Cells(inum, 21).Value
                    For i = 3 To prod + 2
                         sh.cells(i + 1, 2).value = ws.cells(i, 10).value   'ProdName
                         sh.cells(i + 1, 6).value = ws.cells(i, 14).value   'Transaction
                         sh.cells(i + 1, 5).value = ws.cells(i, 12).value  'Weighting
                    Next i
                 Next ProdNum
            End If
    Next
End Sub

上述代码在所有现有工作表之间进行迭代,并仅从数组中选择一个...

【讨论】:

  • 谢谢@FaneDuru 但是,在成本表中,起始位置始终是第 4 行(最初由 i+1 实现。换句话说,当您转到不同的成本表时,您仍然从第 4 行开始。但是,当我们遍历循环时,我希望它从数据表中的第 3 行开始,然后向下移动行。所以在上面的示例表中,您永远不会回到“产品名称 1 " 一个它已被移动到成本 1 表中。
  • @Boswell 我在评论中问过,我也在上面发表了评论......你对以For ProdNum = 5 To TotalAcc + 5 开头的循环有什么期望?现在,上面的代码能满足你的需要吗?如果不是,它对你想要的回报是什么?
  • 抱歉,我在回复时按回车键太早了 - 我会在 2 分钟内回复您的评论。
  • 我已经在上面回复你了。
  • @Boswell 没有人能理解i = ws.Cells(inum, 21).Value,看着你最初的问题......我将它添加到上面的代码中,只是为了感觉它更完整。
猜你喜欢
  • 1970-01-01
  • 2020-02-17
  • 1970-01-01
  • 2023-01-02
  • 2014-09-24
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多