Нахождение номера строки значения в массиве - PullRequest
0 голосов
/ 10 января 2020

Обновление

, поэтому я добавил счетчик, поэтому, если совпадение, добавьте 1 к n. Если нет, то n = 0. Если n = 1, то строка = найденное число. Но почему мне нужно использовать счетчик, почему я не могу использовать свой оригинальный код?

lastrow = (subtaskws.Range("A" & Rows.Count).End(xlUp).row) + 1
lastcol = subtaskws.Cells(2, 1).End(xlToRight).Column
lastcollet = lastcol
lastcollet = Split(Cells(1, lastcol).Address, "$")(1)
lastrowST = subtaskws.Range("A" & Rows.Count).End(xlUp).row
activitynum = AddTask.TextBoxid.Value + 1


Dim Ctrl, ArrayID, userformorder As Variant, j As Long, range1 As Range, os As Integer, col, listitems As String, templatesubtaskrow As Range, tmeplatemilestonerow As Range, newrowadded As Range
userformorder = Array("SubTaskID", "TextBoxsubtask", "ComboBoxDeliverableFormat", "TextBoxcheckedcomplete", "TextBoxformat", "TextBoxacceptancecriteria", "BudgetWorkloadTextBox", "ComboBoxOwner", "TextBoxTDSNumber", "TextBoxMilestone", "TextBoxTargetDeliveryDate", "ComboBoxW", "ComboBoxI", "ComboBoxe", "TextBoxP", "TextBoxLevel", "TextBoxInputQuality", "TextBoxNewInput", "TextBoxDelay", "TextBoxInternalVV", "TextBoxReviewer", "TextBoxDelivered", "ComboBoxNumIterations", "ComboBoxAcceptance", "ComboBoxProgress", "ComboBoxStatus", "ComboBoxFlowChart", "TextBoxActivitySheet", "TextBoxEvidenceofDelivery", "TextBoxComments") 'etc

Set range1 = subtaskws.Range("A3:A" & lastrowST)
Set templatesubtaskrow = subtaskws.Range("A4:" & lastcollet & "4")
ArrayID = range1.Value

With subtaskws
n = 0
For j = LBound(ArrayID) To UBound(ArrayID)
    If ArrayID(j, 1) = activitynum Then
    n = n + 1
    Else
    n = n
    End If
Next j

If n = 1 Then
newrow = j
Else
newrow = lastrow
End If



    Set newrowadded = subtaskws.Range(IDCol & newrow)

Исходный вопрос

У меня есть пользовательская форма, которая заполняет лист с надписью подзадачи. Однако иногда вставляемая информация может быть в середине листа, например. 64-я строка из 140.

Я хочу найти в массиве заданное значение (activtiynum) и, если оно найдено, равно новой строке для этого недавно найденного номера строки. Если activtiynum не найден, newrow должен равняться lastrow + 1.

Однако приведенный ниже код не будет работать и отображает правильный номер строки в msgbox, но затем всегда добавляет новую строку в конце

'find lastrows, columns and cells
lastrow = (subtaskws.Range("A" & Rows.Count).End(xlUp).row) + 1
lastcol = subtaskws.Cells(2, 1).End(xlToRight).Column
lastcollet = lastcol
lastcollet = Split(Cells(1, lastcol).Address, "$")(1)
lastrowST = subtaskws.Range("A" & Rows.Count).End(xlUp).row
activitynum = AddTask.TextBoxid.Value + 1


Dim Ctrl, ArrayID, userformorder As Variant, j As Long, range1 As Range, os As Integer, col, listitems As String, templatesubtaskrow As Range, tmeplatemilestonerow As Range, newrowadded As Range
userformorder = Array("SubTaskID", "TextBoxsubtask", "ComboBoxDeliverableFormat", "TextBoxcheckedcomplete", "TextBoxformat", "TextBoxacceptancecriteria", "BudgetWorkloadTextBox", "ComboBoxOwner", "TextBoxTDSNumber", "TextBoxMilestone", "TextBoxTargetDeliveryDate", "ComboBoxW", "ComboBoxI", "ComboBoxe", "TextBoxP", "TextBoxLevel", "TextBoxInputQuality", "TextBoxNewInput", "TextBoxDelay", "TextBoxInternalVV", "TextBoxReviewer", "TextBoxDelivered", "ComboBoxNumIterations", "ComboBoxAcceptance", "ComboBoxProgress", "ComboBoxStatus", "ComboBoxFlowChart", "TextBoxActivitySheet", "TextBoxEvidenceofDelivery", "TextBoxComments") 'etc

Set range1 = subtaskws.Range("A3:A" & lastrowST)
Set templatesubtaskrow = subtaskws.Range("A4:" & lastcollet & "4")
ArrayID = range1.Value

With subtaskws

For j = LBound(ArrayID) To UBound(ArrayID)
    If ArrayID(j, 1) = activitynum Then
        MsgBox range1(j).row
        newrow = range1(j).row
    Else
        newrow = lastrow
    End If
Next j


   .Range("A" & newrow).EntireRow.Insert


    Set newrowadded = subtaskws.Range(IDCol & newrow)

    templatesubtaskrow.EntireRow.Copy Destination:=newrowadded

1 Ответ

0 голосов
/ 10 января 2020

Исходя из вашего исходного кода, вам нужно что-то сказать, чтобы выйти из FOR L OOP. В противном случае, на следующей итерации после нахождения совпадения он НЕ сможет найти совпадение в следующей ячейке. Это приводит к тому, что код попадает в ваш код ELSE, изменяя newrow на lastrow. Кроме того, причина, по которой вы говорите, что он «находит» его правильно, заключается в том, что вы отображаете окно сообщения, когда оно его находит. Если бы он был перемещен за пределы оператора FOR с помощью 'newrow', он бы не отображал правильное значение.

Самое простое решение, давайте не будем ничего делать в for loop, что нам не нужно, и exit for, когда мы совпадаем. Мы можем установить переменную, указывающую успех, или мы можем использовать вашу переменную newrow (еще не инициализированную / затемненную) для определения успеха.

Примечание. Это работает только потому, что вы не инициализировали newrow как переменную. Возможно, вам придется проверить его на NULL / EMPTY / 0, если вы затемните его для начала.

Также добавлен END WITH. Удалите это, если у вас есть это позже. Должно быть более совместимым с функциональностью.

Set newrowadded = subtaskws.Range(IDCol & newrow) выглядит как IN с оператором with, но ссылается на объект WITH напрямую вместо .Range

См. Обновленный код ниже.

'find lastrows, columns and cells
lastrow = (subtaskws.Range("A" & Rows.Count).End(xlUp).row) + 1
lastcol = subtaskws.Cells(2, 1).End(xlToRight).Column
lastcollet = lastcol
lastcollet = Split(Cells(1, lastcol).Address, "$")(1)
lastrowST = subtaskws.Range("A" & Rows.Count).End(xlUp).row
activitynum = AddTask.TextBoxid.Value + 1


Dim Ctrl, ArrayID, userformorder As Variant, j As Long, range1 As Range, os As Integer, col, listitems As String, templatesubtaskrow As Range, tmeplatemilestonerow As Range, newrowadded As Range
userformorder = Array("SubTaskID", "TextBoxsubtask", "ComboBoxDeliverableFormat", "TextBoxcheckedcomplete", "TextBoxformat", "TextBoxacceptancecriteria", "BudgetWorkloadTextBox", "ComboBoxOwner", "TextBoxTDSNumber", "TextBoxMilestone", "TextBoxTargetDeliveryDate", "ComboBoxW", "ComboBoxI", "ComboBoxe", "TextBoxP", "TextBoxLevel", "TextBoxInputQuality", "TextBoxNewInput", "TextBoxDelay", "TextBoxInternalVV", "TextBoxReviewer", "TextBoxDelivered", "ComboBoxNumIterations", "ComboBoxAcceptance", "ComboBoxProgress", "ComboBoxStatus", "ComboBoxFlowChart", "TextBoxActivitySheet", "TextBoxEvidenceofDelivery", "TextBoxComments") 'etc

Set range1 = subtaskws.Range("A3:A" & lastrowST)
Set templatesubtaskrow = subtaskws.Range("A4:" & lastcollet & "4")
ArrayID = range1.Value

With subtaskws

For j = LBound(ArrayID) To UBound(ArrayID)
    If ArrayID(j, 1) = activitynum Then 'If we match, set newrow to the matched row and then exit the loop
        MsgBox range1(j).row
        newrow = range1(j).row
        Exit For
    End If
Next j

'If newrow is empty it means we didn't match. Add newrow as last row.
If IsEmpty(newrow) Then
    newrow = lastrow
    .Range("A" & newrow).EntireRow.Insert
End If


End With 'Added END WITH as you go back to referencing subtasksws directly not using with syntax

 Set newrowadded = subtaskws.Range(IDCol & newrow)

 templatesubtaskrow.EntireRow.Copy Destination:=newrowadded
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...