简体   繁体   English

VBA 循环到下一个可见单元格

[英]VBA Loop to next visible cell

This is doing my head in now and I cannot seem to get it right, I basically want to loop through column AJ and then if it contains anything like School, it stamps "School" in Column A, however I have a filter on the data because I only need to do this to certain rows..这是我现在的想法,我似乎无法正确处理,我基本上想遍历 AJ 列,然后如果它包含类似学校的任何内容,它会在 A 列中标记“学校”,但是我对数据有一个过滤器因为我只需要对某些行执行此操作..

This code currently returns an error but i believe I am on the right track with it... Just need a pointer if possible please这段代码目前返回一个错误,但我相信我在正确的轨道上......如果可能的话,只需要一个指针

Open to options on this to make things more efficient as I am a bit of a newbie at this.. I effectively need to make loads of filters and conditions so I will be repeating this code multiple times because we output different files based on the bucket column打开选项以使事情更高效,因为我在这方面有点新手。我实际上需要制作大量过滤器和条件,所以我将多次重复此代码,因为我们 output 基于存储桶的不同文件柱子

Below is my revised code which is now working以下是我修改后的代码,现在可以使用

Sub Bucket_macro()
Dim rFiltered As Range, rng As Range, c As Range
Dim lastrow As Long

'Insert Bucket Column
Range("A:A").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("A1").Value = "Bucket"

Range("Q:Q").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("Q1").Value = "Age"

'add formula for DOB
Sheets("Sheet 1").Range("$Q$2:$Q" & Sheets("Sheet 1").Range("C1048574").End(xlUp).Row & "").Formula = "=IF($O2="""","""",DATEDIF($O2,TODAY(),""Y""))"

'filter to NewID only
Sheets("Sheet 1").Range("$A$1:$BQ" & Sheets("Sheet 1").Range("C1048574").End(xlUp).Row & "").AutoFilter Field:=66, Criteria1:="New ID"


lastrow = Range("C1048574").End(xlUp).Row

'first condition based on occupation field
Set rng = Sheets("Sheet 1").Range("AJ2:AJ" & lastrow).SpecialCells(xlCellTypeVisible)

For Each c In rng.SpecialCells(xlCellTypeVisible)
'   c.Select
   If c.Value = "" Then
   'do nothing
   
   Else
        Select Case True
                
            Case (c.Value Like "*school*")
                c.Offset(0, -35).Value = "School"
            
            Case (c.Value Like "*nursery*")
                c.Offset(0, -35).Value = "School"

            Case (c.Value Like "*university*")
                c.Offset(0, -35).Value = "School"
                
            Case (c.Value Like "*university*")
                c.Offset(0, -35).Value = "School"
            
            Case (c.Value Like "*education*")
                c.Offset(0, -35).Value = "School"
                
            Case (c.Value Like "*college*")
                c.Offset(0, -35).Value = "School"
        End Select
    
    End If

Next c

'Next condition based on age
Set rng = Sheets("Sheet 1").Range("Q2:Q" & lastrow).SpecialCells(xlCellTypeVisible)

For Each c In rng.SpecialCells(xlCellTypeVisible)
'   c.Select
   If c.Value = "" Then
   'do nothing
   
   Else
        Select Case True
                
            Case (c.Value < 19)
                    c.Offset(0, -16).Value = "School"
                    
            End Select
    
    End If

Next c

'Next condition based on job.description
Set rng = Sheets("Sheet 1").Range("AN2:AN" & lastrow).SpecialCells(xlCellTypeVisible)

For Each c In rng.SpecialCells(xlCellTypeVisible)
'   c.Select
   If c.Value = "" Then
   'do nothing
   
   Else
        Select Case True
                
            Case (c.Value Like "*school*")
                c.Offset(0, -39).Value = "School"
                
            Case (c.Value Like "*academy*")
                c.Offset(0, -39).Value = "School"
                
            Case (c.Value Like "*college*")
                c.Offset(0, -39).Value = "School"
                
            Case (c.Value Like "*university*")
                c.Offset(0, -39).Value = "School"
                
            Case (c.Value Like "*nursery*")
                c.Offset(0, -39).Value = "School"
                    
            End Select
    
    End If

Next c

End Sub

It looks like you're at the early stages of your VBA learning, I think we can all remember what that was like.看起来你正处于 VBA 学习的早期阶段,我想我们都记得那是什么样的。 There's a number of observations and suggestions worth mentioning about your code.关于您的代码,有许多值得一提的观察和建议。 I've provided an alternative below with comments explaining what certain different parts are for etc.我在下面提供了一个替代方案,其中包含解释某些不同部分的用途等的注释。

There's nothing wrong with using a Case… approach, or even an If..Else If method.使用Case…方法,甚至是If..Else If方法都没有错。 I've taken a slightly different approach in an effort to reduce the number of lines of code needed.我采取了一种稍微不同的方法来减少所需的代码行数。

I'm not sure I like your overall approach – once you start inserting columns in a module that references specific columns, you can only run the code once – lest you end up in a very confused state.我不确定我是否喜欢你的整体方法——一旦你开始在引用特定列的模块中插入列,你只能运行一次代码——以免你最终陷入非常困惑的 state。 It was a bit tricky following your references as it was, and you may need to make some adjustments to suit.照原样遵循您的参考有点棘手,您可能需要进行一些调整以适应。 You don't turn the filter off at the end of your module – so I didn't either.你不会在模块结束时关闭过滤器——所以我也没有。

It works for me, let me know how you go with it.它对我有用,让我知道你如何使用它 go。

    Option Compare Text '<~~ to ignore case in text comparisons
    Option Explicit     '<~~ to force declaration of all variables
    Sub Bucket_macro()
    'Declare all variables used
    Dim ws As Worksheet, c As Range, LastRow As Long, i
    
    Set ws = Worksheets("Sheet 1")              '<~~ change to whatever you called sheet 1
        
    ws.Range("A:A").Insert                      '<~~ insert both columns
    ws.Range("Q:Q").Insert                  
    
    ws.Range("A1").Value = "Bucket"             '<~~ add headings
    ws.Range("Q1").Value = "Age"
    
    LastRow = ws.Cells(Rows.Count, 3).End(xlUp).Row '<~~ get last row early
    
    'Add age formula
    With ws.Range("Q2:Q" & LastRow)
        .FormulaR1C1 = "=IF(RC15<>"""",DATEDIF(RC15, TODAY(),""Y""),"""")"
        .Value = .Value
    End With
    
    'Set filter on column BN to "New ID" only 
    ws.Range("BN:BN").AutoFilter Field:=1, Criteria1:="New ID"
    
    'First condition: based on Occupation
    For Each c In ws.Range("AJ2:AJ" & LastRow).SpecialCells(xlCellTypeVisible)
        For Each i In Array("school", "nursery", "university", "education", "college")
            If InStr(c.Value, i) > 0 Then ws.Cells(c.Row, 1).Value = "School"
        Next i
    Next c
    
    'Second condition: based on age
    For Each c In ws.Range("Q2:Q" & LastRow).SpecialCells(xlCellTypeVisible)
        If c.Value < 19 Then ws.Cells(c.Row, 1).Value = "School"
    Next c
    
    'Third condition: based on job description
    For Each c In ws.Range("AN2:AN" & LastRow).SpecialCells(xlCellTypeVisible)
        For Each i In Array("school", "academy", "college", "university", "nursery")
            If InStr(c.Value, i) > 0 Then ws.Cells(c.Row, 1).Value = "School"
        Next i
    Next c
    
    End Sub

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

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