Как мне заставить цикл For Next действительно зацикливаться?

У меня есть цикл, однако он находит только первую итерацию и не переходит к следующей итерации.

Я установил цикл. На данный момент он открывает лист под названием «Имена», подсчитывает строки, содержащие IMP и EXP, и присваивает их переменной. Рабочий лист «Имена» содержит список. Столбец A — это инициалы пользователя, столбец B — имя пользователя, а столбец C содержит IMP или EXP в зависимости от пользователя. Затем макрос открывает лист под названием «Средние» и запускает цикл.

Цикл начинается со счетчика For, равного количеству строк IMP. Устанавливает диапазон с помощью счетчика. Затем он просматривает лист «Имена» и находит в нем строку с IMP. Если ячейка содержит данные, задается номер строки. Затем он устанавливает переменную ячейку rng и устанавливает ее в текущую строку IMP и две ячейки слева. (Пользовательский инициал) и продолжает устанавливать ячейку rng вправо и устанавливает ее в текущую строку IMP и 1 ячейку влево. (Имя пользователя).

Итак, этот тип работы работает. Он выполняет цикл 10 раз, как и должно быть, однако моя проблема в том, что он находит первую строку IMP и вводит инициал пользователя, а затем имя. Но просто копируйте это 10 раз вместо того, чтобы просматривать следующую строку с IMP и вводить инициал и имя следующего пользователя. Таким образом, я получаю 10 строк, состоящих только из инициалов и имени одного человека. Мне трудно разобраться в циклах. Может ли кто-нибудь показать мне мою ошибку? Код ниже.

Worksheets("Names").Activate

Range("C2").Select
'counts the rows
 IMPRows = Application.WorksheetFunction.CountIf(Range("C:C"), "IMP")
 EXPRows = Application.WorksheetFunction.CountIf(Range("C:C"), "EXP")

Worksheets("Averages").Activate

 
'Start of loop to insert data 
 For counter = 6 To 6 + IMPRows
 Set rng = Worksheets("Averages").Cells(counter, 1)
 
 Set rng2 = Worksheets("Names").Columns("C:C").Find(What: = "IMP", MatchCase:=True)
    If Not rng2 Is Nothing Then
    rownumber = rng2.Row
    rng.Offset(0, 0) = rng2.Offset(0, -2)
    rng.Offset(0, 1) = rng2.Offset(0, -1)
    Else
    End If
   
'end of loop
 Next counter

Во-первых, научитесь правильно делать отступы в коде. Это значительно упрощает отслеживание хода выполнения и выявление логических ошибок. Далее, не используйте предложение Else, если вам не нужно, чтобы что-то произошло в этом Else состоянии. Наконец, научитесь использовать отладчик для установки точек останова, чтобы вы могли пошагово выполнять код по мере его выполнения и точно видеть, что происходит. Это помогает вам оценить содержимое переменных и проследить точный ход выполнения кода.

Ken White 24.07.2024 06:32

Похоже, вы пытаетесь перестроить встроенную функцию ФИЛЬТР?

CLR 24.07.2024 08:58

Чтобы ответить на логику вашего вопроса, вы выполняете цикл, но каждый раз выполняете один и тот же поиск. Чтобы получить более поздние результаты, вам нужно использовать .FindNext и указать, что он должен начать следить за вашим последним результатом.

Tragamor 24.07.2024 11:18
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
3
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поиск с использованием метода Find

Option Explicit

Sub LookupIMP()

    Const SEARCH_STRING As String = "IMP"

    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    Dim sws As Worksheet: Set sws = wb.Sheets("Names")
    Dim srg As Range:
    Set srg = sws.Range("C2", sws.Cells(sws.Rows.Count, "C").End(xlUp))
    
    Dim dws As Worksheet: Set dws = wb.Sheets("Averages")
    Dim dcell As Range: Set dcell = dws.Range("A6")
    
    Dim scell As Range: Set scell = srg.Find(What:=SEARCH_STRING, _
        After:=srg.Cells(srg.Cells.Count), LookIn:=xlValues, LookAt:=xlWhole, _
        MatchCase:=True)
    
    If scell Is Nothing Then
        MsgBox "No occurrence of """ & SEARCH_STRING & """ found!", _
           vbExclamation
        Exit Sub
    End If
        
    Dim sFirstAddress As String: sFirstAddress = scell.Address
    
    Do
        dcell.Offset(, 0).Value = scell.Offset(, -2).Value
        dcell.Offset(, 1).Value = scell.Offset(, -1).Value
        Set dcell = dcell.Offset(1)
        Set scell = srg.FindNext(After:=scell)
    Loop While scell.Address <> sFirstAddress

    MsgBox "Looking up """ & SEARCH_STRING & """ finished.", _
        vbInformation
    
End Sub

Спасибо VBasic! По какой-то причине сразу это не сработало. У меня были ошибки, но я установил wb как фактическое имя листа Excel вместо просто «ThisWorkbook», а также установил sws как wb,Worksheets («Имена»). Опять же, не знаю почему, но их изменение устранило ошибку. Спасибо за вашу помощь. очень ценю.

One foot in the Grave 24.07.2024 23:50

Альтернативой использованию ADO с учетом регистра является:

Sub Test()
    Dim adoCN As Object, RS As Object
    Dim myFile As String, strSQL As String
    
    myFile = ThisWorkbook.FullName
    
    Set adoCN = CreateObject("ADODB.Connection")
    Set RS = CreateObject("ADODB.Recordset")
    
    adoCN.Provider = "Microsoft.ACE.OLEDB.12.0"
    adoCN.Properties("Data Source") = myFile
    adoCN.Properties("Extended Properties") = "Excel 12.0 Macro; HDR=Yes; IMEX=1"
    adoCN.Open
    
    strSQL = "Select [Name], [Num] From [Names$] Where StrComp([Crit], 'IMP', 0) = 0"
    RS.Open strSQL, adoCN
    
    Sheets("Averages").Range("A2").CopyFromRecordset RS
    
    RS.Close
    
    Set RS = Nothing
    Set adoCN = Nothing
End Sub

Спасибо, Халук. К сожалению, из-за моих ограниченных знаний это слишком сложно для понимания.

One foot in the Grave 24.07.2024 23:51

Другие вопросы по теме