Если с узлом ничего не нужно делать, то просто удалите выход из процедуры (Exit Sub) и добавте перебор на следующий список [vba]
Код
MsgBox "Не разузлован: " & st(p, 0), 48, "ВНИМАНИЕ": p = p - 1
[/vba] А лучше добавить эту информацию в результат. Замените предыдущую строку на вот это [vba]
Код
If d.Exists(st(p, 0)) Then tmp = d(st(p, 0)) tmp(3) = tmp(3) + k d(st(p, 0)) = tmp Else ReDim tmp(1 To 3) tmp(1) = st(p, 0) tmp(2) = "!!!Не разузлован" tmp(3) = k d.Add st(p, 0), tmp End If p = p - 1
Если с узлом ничего не нужно делать, то просто удалите выход из процедуры (Exit Sub) и добавте перебор на следующий список [vba]
Код
MsgBox "Не разузлован: " & st(p, 0), 48, "ВНИМАНИЕ": p = p - 1
[/vba] А лучше добавить эту информацию в результат. Замените предыдущую строку на вот это [vba]
Код
If d.Exists(st(p, 0)) Then tmp = d(st(p, 0)) tmp(3) = tmp(3) + k d(st(p, 0)) = tmp Else ReDim tmp(1 To 3) tmp(1) = st(p, 0) tmp(2) = "!!!Не разузлован" tmp(3) = k d.Add st(p, 0), tmp End If p = p - 1
miver, дело в том, что номер из ячейки В3 и последующие с листа "Перечень", а также номера разузловываемых узлов не должены попадать в список на лист "Итог", иначе кол-во узлов удваивается, утраивается и т.д. а в остальном очень даже достойный вариант, по крайней мере можно работать даже без карандаша
miver, дело в том, что номер из ячейки В3 и последующие с листа "Перечень", а также номера разузловываемых узлов не должены попадать в список на лист "Итог", иначе кол-во узлов удваивается, утраивается и т.д. а в остальном очень даже достойный вариант, по крайней мере можно работать даже без карандаша ZamoK
Я не Гуру, но стремлюсь!
Сообщение отредактировал ZamoK - Среда, 22.07.2015, 16:03
Подробно: 1) Берём номер из ячейки В3 лист "Перечень" (сам номер вписывать на лист "Итог" не нужно) 2) Ищем соответствие на листе "Состав узлов" в столбце А, копирует перечисленный состав из столбцов CDE до первой пустой ячейки на лист "Итог". 3) Затем находим из вновь добавленных позиций номера начинающиеся на 3 и 6 (это узлы и их нужно разобрать по деталям)-но сам номер повторно вписывать на лист "Итог" не нужно, только добавлять его составляющие 4) Берём найденый номер на 3(6) далее пункт 2,3,4 пока не закончатся в добавленных позициях номера на 3 и 6. 4.1) Если номера на листе "Состав узлов" в столбце А нет, то выдаём сообщение ... при нажатии ОК продолжаем 2,3,4 5) Затем следующая ячейка с листа "Перечень" - В4, и повторяются п.2,3,4,5 до пустой ячейки.
И если деталь не разузлована подписывать это в итоге оч хорошая идея!
Подробно: 1) Берём номер из ячейки В3 лист "Перечень" (сам номер вписывать на лист "Итог" не нужно) 2) Ищем соответствие на листе "Состав узлов" в столбце А, копирует перечисленный состав из столбцов CDE до первой пустой ячейки на лист "Итог". 3) Затем находим из вновь добавленных позиций номера начинающиеся на 3 и 6 (это узлы и их нужно разобрать по деталям)-но сам номер повторно вписывать на лист "Итог" не нужно, только добавлять его составляющие 4) Берём найденый номер на 3(6) далее пункт 2,3,4 пока не закончатся в добавленных позициях номера на 3 и 6. 4.1) Если номера на листе "Состав узлов" в столбце А нет, то выдаём сообщение ... при нажатии ОК продолжаем 2,3,4 5) Затем следующая ячейка с листа "Перечень" - В4, и повторяются п.2,3,4,5 до пустой ячейки.
И если деталь не разузлована подписывать это в итоге оч хорошая идея!
miver, Ну да теперь все совпадает . только вот[vba]
Код
Else ReDim tmp(1 To 3) tmp(1) = st(p, 0) tmp(2) = "!!!Не разузлован" tmp(3) = k d.Add st(p, 0), tmp
[/vba] зачем это в коде если не работает? А хотелось бы чтоб работало. Да и ещё возьмите последний узел с листа состав узлов и попробуйте его заполнить. Ошибочка тут:s = Trim(struct(i, 3)) [vba]
Код
End If i = i + 1 s = Trim(struct(i, 3)) Wend Else MsgBox "Не разузлован: " & st(p, 0), 48, "ВНИМАНИ
[/vba] если через пустую строчку вниз заполниить ячейки, то работает
miver, Ну да теперь все совпадает . только вот[vba]
Код
Else ReDim tmp(1 To 3) tmp(1) = st(p, 0) tmp(2) = "!!!Не разузлован" tmp(3) = k d.Add st(p, 0), tmp
[/vba] зачем это в коде если не работает? А хотелось бы чтоб работало. Да и ещё возьмите последний узел с листа состав узлов и попробуйте его заполнить. Ошибочка тут:s = Trim(struct(i, 3)) [vba]
Код
End If i = i + 1 s = Trim(struct(i, 3)) Wend Else MsgBox "Не разузлован: " & st(p, 0), 48, "ВНИМАНИ
[/vba] если через пустую строчку вниз заполниить ячейки, то работаетZamoK
Я не Гуру, но стремлюсь!
Сообщение отредактировал ZamoK - Пятница, 24.07.2015, 13:18
Я правда не знаю, что такое рекурсия, но бросить на пол пути тему которую создал - как-то не правильно! Может решение таким способом комуто будет более приемлимо, ведь данные могут быть разными, и я не единственный в мире кто выполняет такого рода работу
SLAVICK, Никаких вопросов файл полностью устраивает, все отлично. Вот miver, просто хочет предложить решение немного другим спосом (без рекурсии)
Я правда не знаю, что такое рекурсия, но бросить на пол пути тему которую создал - как-то не правильно! Может решение таким способом комуто будет более приемлимо, ведь данные могут быть разными, и я не единственный в мире кто выполняет такого рода работу ZamoK
Для общего развития ознакомьтесь Wiki - рекурсия особенно уделите внимание разделу "в программировании" Для определения более быстрого метода нужно протестировать при необходимости перебора порядка 10000 записей. Тогда и узнаете, какой лучше.
Для общего развития ознакомьтесь Wiki - рекурсия особенно уделите внимание разделу "в программировании" Для определения более быстрого метода нужно протестировать при необходимости перебора порядка 10000 записей. Тогда и узнаете, какой лучше.
Sub main() 'with using reference MS Scripting Runtime
Dim arr, s, i&, p&, d As New Dictionary, st_dic As New Dictionary Dim struct, key, k Dim st() Dim tmp() Dim rez()
ReDim st(0 To 100, 0 To 2) p = 0 d.CompareMode = 1
struct = Лист5.Range("A3", "E" & Лист5.Range("C60000").End(xlUp).Row + 1).Value For i = 1 To UBound(struct) If Len(struct(i, 1)) Then If Not st_dic.Exists(struct(i, 1)) Then st_dic.Add struct(i, 1), i End If Next i
For i = 1 To UBound(arr) If Len(Trim(arr(i, 1))) Then p = p + 1 st(p, 0) = Trim(arr(i, 1)) st(p, 1) = Trim(arr(i, 3)) End If Next i Erase arr
While p > 0 If st_dic.Exists(st(p, 0)) Then k = st(p, 1) i = st_dic(st(p, 0)) p = p - 1 s = Trim(struct(i, 3)) While Not s = "" If Left(s, 1) = 3 Or Left(s, 1) = 6 Then p = p + 1 st(p, 0) = s st(p, 1) = struct(i, 5) * k 'Было st(p, 1) = Val(struct(i, 5)) * k st(p, 2) = 1 End If If d.Exists(s) Then tmp = d(s) Else ReDim tmp(1 To 3) tmp(1) = s d.Add s, tmp End If tmp(2) = struct(i, 4) tmp(3) = tmp(3) + struct(i, 5) * k 'Было tmp(3) = tmp(3) + Val(struct(i, 5)) * k d(s) = tmp i = i + 1 s = Trim(struct(i, 3)) Wend Else MsgBox "Не разузлован: " & st(p, 0), 48, "ВНИМАНИЕ": If st(p, 2) = 1 Then If d.Exists(st(p, 0)) Then tmp = d(st(p, 0)) Else ReDim tmp(1 To 3) tmp(1) = st(p, 0) d.Add st(p, 0), tmp End If tmp(2) = "!!!Не разузлован" tmp(3) = tmp(3) + k d(st(p, 0)) = tmp End If p = p - 1 End If Wend
Erase struct ReDim rez(1 To d.Count, 1 To 4) p = 0 For Each key In d.Keys p = p + 1 rez(p, 1) = p For i = 1 To 3 rez(p, i + 1) = d(key)(i) Next i Next key d.RemoveAll
With Sheets("Итог").Range("A3:D3") .CurrentRegion.Offset(2).ClearContents .Resize(p).Value = rez() .Parent.Activate End With Range("E3").Select End Sub
[/vba]
[vba]
Код
Sub main() 'with using reference MS Scripting Runtime
Dim arr, s, i&, p&, d As New Dictionary, st_dic As New Dictionary Dim struct, key, k Dim st() Dim tmp() Dim rez()
ReDim st(0 To 100, 0 To 2) p = 0 d.CompareMode = 1
struct = Лист5.Range("A3", "E" & Лист5.Range("C60000").End(xlUp).Row + 1).Value For i = 1 To UBound(struct) If Len(struct(i, 1)) Then If Not st_dic.Exists(struct(i, 1)) Then st_dic.Add struct(i, 1), i End If Next i
For i = 1 To UBound(arr) If Len(Trim(arr(i, 1))) Then p = p + 1 st(p, 0) = Trim(arr(i, 1)) st(p, 1) = Trim(arr(i, 3)) End If Next i Erase arr
While p > 0 If st_dic.Exists(st(p, 0)) Then k = st(p, 1) i = st_dic(st(p, 0)) p = p - 1 s = Trim(struct(i, 3)) While Not s = "" If Left(s, 1) = 3 Or Left(s, 1) = 6 Then p = p + 1 st(p, 0) = s st(p, 1) = struct(i, 5) * k 'Было st(p, 1) = Val(struct(i, 5)) * k st(p, 2) = 1 End If If d.Exists(s) Then tmp = d(s) Else ReDim tmp(1 To 3) tmp(1) = s d.Add s, tmp End If tmp(2) = struct(i, 4) tmp(3) = tmp(3) + struct(i, 5) * k 'Было tmp(3) = tmp(3) + Val(struct(i, 5)) * k d(s) = tmp i = i + 1 s = Trim(struct(i, 3)) Wend Else MsgBox "Не разузлован: " & st(p, 0), 48, "ВНИМАНИЕ": If st(p, 2) = 1 Then If d.Exists(st(p, 0)) Then tmp = d(st(p, 0)) Else ReDim tmp(1 To 3) tmp(1) = st(p, 0) d.Add st(p, 0), tmp End If tmp(2) = "!!!Не разузлован" tmp(3) = tmp(3) + k d(st(p, 0)) = tmp End If p = p - 1 End If Wend
Erase struct ReDim rez(1 To d.Count, 1 To 4) p = 0 For Each key In d.Keys p = p + 1 rez(p, 1) = p For i = 1 To 3 rez(p, i + 1) = d(key)(i) Next i Next key d.RemoveAll
With Sheets("Итог").Range("A3:D3") .CurrentRegion.Offset(2).ClearContents .Resize(p).Value = rez() .Parent.Activate End With Range("E3").Select End Sub