Здравствуйте уважаемые форумчане. Вопрос состоит в следующем, в файле примере имеется исходный лист "МИРВОЙНА" и лист результатов "ППСС". МИРВОЙНА содержит название должностей их коды и названия подразделений, а также убытие и прибытие сотрудников при перемещении. В ППСС содержится пример результата такого плана. Мой вопрос состоит в том, как получить указанный результат БЕЗ ИСПОЛЬЗОВАНИЯ ЦИКЛОВ и СРАВНЕНИЙ, так как с циклами программа работает очень долго... Заранее спасибо.
Здравствуйте уважаемые форумчане. Вопрос состоит в следующем, в файле примере имеется исходный лист "МИРВОЙНА" и лист результатов "ППСС". МИРВОЙНА содержит название должностей их коды и названия подразделений, а также убытие и прибытие сотрудников при перемещении. В ППСС содержится пример результата такого плана. Мой вопрос состоит в том, как получить указанный результат БЕЗ ИСПОЛЬЗОВАНИЯ ЦИКЛОВ и СРАВНЕНИЙ, так как с циклами программа работает очень долго... Заранее спасибо.Sashagor1982
Не плохо, только не заполняется количество. И если одинаково, как в примере "номер расчета", то дублировать не надо. И конечно, же хотелось бы без циклов, с коллекциями например, хотя я не особый спец.
Не плохо, только не заполняется количество. И если одинаково, как в примере "номер расчета", то дублировать не надо. И конечно, же хотелось бы без циклов, с коллекциями например, хотя я не особый спец.Sashagor1982
Skif-F, видно, что вы неплохо знаете VBA, но в вашем коде есть несколько мест, на которые стоит обратить внимание... (я их прокомментировал, в вашем модуле - см. вложенный файл из моего предыдущего поста)
Sashagor1982, в моем решении, для проверки на уникальность, используются аж 4 поля (в точности, как было описано у вас - "кол-во одинаковых перемещений, т.е. должность убытия и прибытия , наименование подразделенияодинаковы для нескольких перемещений"). Это точно не избыточно? Т.е., у вас могут быть ситуации, например, когда будут совпадать все условия, кроме одного? Мне, все-таки, кажется, что это избыточные условия и если вы просчитаете все возможные варианты, эти проверки можно упростить... (но не навязываю! просто, советую, а решать вам. хотя если вас устраивает скорость выполнения, то можно забить на оптимизацию ) Мой код - весь в отдельном модуле, но в вашем модуле я поправил функцию WorksheetIsExist() - просто, нет смысла сравнивать в цикле имена всех листов книги, если задача решается в один ход.
Skif-F, видно, что вы неплохо знаете VBA, но в вашем коде есть несколько мест, на которые стоит обратить внимание... (я их прокомментировал, в вашем модуле - см. вложенный файл из моего предыдущего поста)
Sashagor1982, в моем решении, для проверки на уникальность, используются аж 4 поля (в точности, как было описано у вас - "кол-во одинаковых перемещений, т.е. должность убытия и прибытия , наименование подразделенияодинаковы для нескольких перемещений"). Это точно не избыточно? Т.е., у вас могут быть ситуации, например, когда будут совпадать все условия, кроме одного? Мне, все-таки, кажется, что это избыточные условия и если вы просчитаете все возможные варианты, эти проверки можно упростить... (но не навязываю! просто, советую, а решать вам. хотя если вас устраивает скорость выполнения, то можно забить на оптимизацию ) Мой код - весь в отдельном модуле, но в вашем модуле я поправил функцию WorksheetIsExist() - просто, нет смысла сравнивать в цикле имена всех листов книги, если задача решается в один ход.KSV
[offtop]Зачем закладывать "запас прочности", если он останется невостребованным? Зачем вообще "запас прочности", если кол-во необходимых строк в результ. массиве известно (можно узнать) сразу? Я не собирался вас "ругать" и прошу прощения, если мои комментарии вас обидели. Я лишь пытался показать вам "узкие места" (которые можно легко оптимизировать) в вашем коде. А вы, хотите - прислушивайтесь, не хотите - пишите по-своему, это ваше решение...
VBA позволяет расширять массив "по столбцам", а нам надо "по строкам"
По какой причине вы использовали доп. массив Рез - я понимаю... Я просто пытался вам объяснить, что можно было легко обойтись одним результ. массивом и не перезаписываться из одного массива в другой. Если объяснить не получилось, то можете посмотреть пример в моем модуле, в том же файле. А если вам это не интересно, то просто забейте...
[p.s.]Я не хочу с вами спорить и утверждать, что мое мнение "правильнее" вашего. Я просто дал вам советы по оптимизации вашего кода, а принимать их или нет - это ваше дело. Оправдываться передо мной за те или иные решения в вашем коде тоже не нужно - я вам не судья и не экзаменатор. Дискуссию продолжать тоже не имеет смысла, тем более в этой теме.
[offtop]Зачем закладывать "запас прочности", если он останется невостребованным? Зачем вообще "запас прочности", если кол-во необходимых строк в результ. массиве известно (можно узнать) сразу? Я не собирался вас "ругать" и прошу прощения, если мои комментарии вас обидели. Я лишь пытался показать вам "узкие места" (которые можно легко оптимизировать) в вашем коде. А вы, хотите - прислушивайтесь, не хотите - пишите по-своему, это ваше решение...
VBA позволяет расширять массив "по столбцам", а нам надо "по строкам"
По какой причине вы использовали доп. массив Рез - я понимаю... Я просто пытался вам объяснить, что можно было легко обойтись одним результ. массивом и не перезаписываться из одного массива в другой. Если объяснить не получилось, то можете посмотреть пример в моем модуле, в том же файле. А если вам это не интересно, то просто забейте...
[p.s.]Я не хочу с вами спорить и утверждать, что мое мнение "правильнее" вашего. Я просто дал вам советы по оптимизации вашего кода, а принимать их или нет - это ваше дело. Оправдываться передо мной за те или иные решения в вашем коде тоже не нужно - я вам не судья и не экзаменатор. Дискуссию продолжать тоже не имеет смысла, тем более в этой теме.KSV
' Загоняем в словарь только нужное, а не все подряд For Each c In .Columns(2).SpecialCells(xlCellTypeFormulas) Dict.Add c.Value, c.Row Next
[/vba] Данные берутся со столбца "убывает"? И еще, если перед помещение в лист результат надо не просто вставлять значения, а проводить какие либо операции, например ВУС делить по три цифры и заполнять 3,4 и 10,11 столбцы листа-результата или проводить сравнение, например если в листе МИРВОЙНА столбец I содержит значение НЕТ, то данное перемещение не рассматривать, подскажите в каком месте изменить код? Заранее Спасибо
KSV, Я не понял несколько моментов [vba]
Код
' Загоняем в словарь только нужное, а не все подряд For Each c In .Columns(2).SpecialCells(xlCellTypeFormulas) Dict.Add c.Value, c.Row Next
[/vba] Данные берутся со столбца "убывает"? И еще, если перед помещение в лист результат надо не просто вставлять значения, а проводить какие либо операции, например ВУС делить по три цифры и заполнять 3,4 и 10,11 столбцы листа-результата или проводить сравнение, например если в листе МИРВОЙНА столбец I содержит значение НЕТ, то данное перемещение не рассматривать, подскажите в каком месте изменить код? Заранее СпасибоSashagor1982
Этот цикл проходит по непустым ячейкам в столбце W. Если говорить о файле-примере, то это будет всего 4 итерации. И при этом, в словарь мы занесем тоже всего 4 значения (номера строк для упр.5, УСАДН3 и т.д), которые нам понадобятся в след. цикле. След. цикл - тоже всего 4 итерации, по непустым ячейкам в столбце V. При этом, на каждом шаге этого (второго) цикла, без каких-либо проверок, мы уже имеем полную информацию по убытии и прибытии одного из 4-х перемещений, поэтому на каждой итерации мы заполняем полностью всю "строчку" результ. массива, кроме кол-ва. (каждая "строчка" результ. массива соответствует одной строке таблицы на листе "ППСС", т.е., за эти 4 итерации мы заполняем всю таблицу). А 2 последние строки второго цикла, подготавливают данные для подсчета кол-ва, задавая уникальность ключа, по указанным вами условиям, и если ключ повторяется, то в словарь не добавляется новая запись, а инкрементируется значение по этому ключу. Таким образом, после выхода из этого второго цикла у нас уже есть ВСЕ данные для заполнения таблицы, и все они, кроме кол-ва, уже записаны в результ. массив, и в нужные ячейки. А данные по кол-ву тоже уже готовы, но только лежат во втором словаре. И след. циклом "For i = 1 To j" (тоже всего 4 итерации) мы переносим эти данные о кол-ве в нужные ячейки результ. массива. Все, массив готов! Остается только скопировать его в нужное место таблицы. Это и делается последними строками макроса. Да, вы лучше дебагером один раз пройдите по шагам и все сразу станет понятно. Ну, на первый взгляд, код может показаться непонятным (хотя, я практически каждую строчку прокоментировал), но это та небольшая цена, которую приходится платить за быстрые алгоритмы Зато, никаких проверок и никаких лишних телодвижений - три коротеньких цикла и все условия задачи выполнены
Этот цикл проходит по непустым ячейкам в столбце W. Если говорить о файле-примере, то это будет всего 4 итерации. И при этом, в словарь мы занесем тоже всего 4 значения (номера строк для упр.5, УСАДН3 и т.д), которые нам понадобятся в след. цикле. След. цикл - тоже всего 4 итерации, по непустым ячейкам в столбце V. При этом, на каждом шаге этого (второго) цикла, без каких-либо проверок, мы уже имеем полную информацию по убытии и прибытии одного из 4-х перемещений, поэтому на каждой итерации мы заполняем полностью всю "строчку" результ. массива, кроме кол-ва. (каждая "строчка" результ. массива соответствует одной строке таблицы на листе "ППСС", т.е., за эти 4 итерации мы заполняем всю таблицу). А 2 последние строки второго цикла, подготавливают данные для подсчета кол-ва, задавая уникальность ключа, по указанным вами условиям, и если ключ повторяется, то в словарь не добавляется новая запись, а инкрементируется значение по этому ключу. Таким образом, после выхода из этого второго цикла у нас уже есть ВСЕ данные для заполнения таблицы, и все они, кроме кол-ва, уже записаны в результ. массив, и в нужные ячейки. А данные по кол-ву тоже уже готовы, но только лежат во втором словаре. И след. циклом "For i = 1 To j" (тоже всего 4 итерации) мы переносим эти данные о кол-ве в нужные ячейки результ. массива. Все, массив готов! Остается только скопировать его в нужное место таблицы. Это и делается последними строками макроса. Да, вы лучше дебагером один раз пройдите по шагам и все сразу станет понятно. Ну, на первый взгляд, код может показаться непонятным (хотя, я практически каждую строчку прокоментировал), но это та небольшая цена, которую приходится платить за быстрые алгоритмы Зато, никаких проверок и никаких лишних телодвижений - три коротеньких цикла и все условия задачи выполнены KSV
а проводить какие либо операции, например ВУС делить по три цифры и заполнять 3,4 и 10,11 столбцы листа-результата
Вы можете это сделать, например, во втором цикле, и сразу поместить нужные значения в нужные ячейки результ. массива, или позже, в любом месте программы, до копирования результ. массива в таблицу.
Тоже самое - просто занесите нужные значения в нужные ячейки массива (какие ячейки нужные, можно понять спроецировав результ. массив на таблицу, на листе "ППСС")
например если в листе МИРВОЙНА столбец I содержит значение НЕТ, то данное перемещение не рассматривать, подскажите в каком месте изменить код?
для этого нужно будет не менять код, а дописывать (например, предварительно устанавливать фильтр), а в существующем коде ничего менять не нужно - в нем нет "лишних" строк, а каждая существующая команда - нужна и важна [p.s.]Каждая строка кода прокомментирована, + Я полностью описал вам логику алгоритма и практически расписал построчно... Надеюсь, теперь этот код для вас стал понятным.[/p.s.]
а проводить какие либо операции, например ВУС делить по три цифры и заполнять 3,4 и 10,11 столбцы листа-результата
Вы можете это сделать, например, во втором цикле, и сразу поместить нужные значения в нужные ячейки результ. массива, или позже, в любом месте программы, до копирования результ. массива в таблицу.
Тоже самое - просто занесите нужные значения в нужные ячейки массива (какие ячейки нужные, можно понять спроецировав результ. массив на таблицу, на листе "ППСС")
например если в листе МИРВОЙНА столбец I содержит значение НЕТ, то данное перемещение не рассматривать, подскажите в каком месте изменить код?
для этого нужно будет не менять код, а дописывать (например, предварительно устанавливать фильтр), а в существующем коде ничего менять не нужно - в нем нет "лишних" строк, а каждая существующая команда - нужна и важна [p.s.]Каждая строка кода прокомментирована, + Я полностью описал вам логику алгоритма и практически расписал построчно... Надеюсь, теперь этот код для вас стал понятным.[/p.s.]KSV
И еще, ..., подскажите в каком месте изменить код?
Информация к размышлению в прилагаемом файле. Запустите свой и мой варианты. Да, ещё попробуйте нажать отмену, когда программа спросит о необходимости удалять существующий лист.
P.S. Случаи разные бывают, а заказчики - очень непредсказуемые люди.
И еще, ..., подскажите в каком месте изменить код?
Информация к размышлению в прилагаемом файле. Запустите свой и мой варианты. Да, ещё попробуйте нажать отмену, когда программа спросит о необходимости удалять существующий лист.
P.S. Случаи разные бывают, а заказчики - очень непредсказуемые люди.Skif-F
Вроди бы общаемся на одном языке, но вы меня не понимаете (или делаете вид)... Я вам объяснил и показал в своем коде, что нет смысла тратить время и ресурсы на проверку и наращивание массива в цикле, если мы МОЖЕМ СРАЗУ УЗНАТЬ ЕГО РАЗМЕР. Тем более, что данный случай, позволяет реализовать алгоритм вообще БЕЗ ЕДИНОЙ проверки каких-либо условий (см. мой код) Я не пытался доказать, что мой алгоритм хороший, а ваш - плохой (а по-сути, у нас просто разные реализации, практически, одного алгоритма ), я лишь пытался вам объяснить, что оптимизировав свой код (убрав из циклов "лишние" действия), вы сделаете его еще быстрее! Хотя он и так достаточно быстрый и при некоторых условиях догоняет и даже обгоняет мой! (про "узкие места" в моем коде я знаю - могу исправить, но попозже...)
Ну, да, при отмене вываливалась ошибка, но косяк же был не в моем коде, а в процедуре "ВнешнийВид"... (исправил) И вообще, существование листа "ППСС" логичнее проверять ДО формирования плана перемещений, а иначе, какой смысл его формировать, если в конце пользователь откажется от удаления листа...
А такой ситуации быть не должно, т.к. я ему еще изначально делал выбор из списка (для удобства) и подсветку некоторых возможных ошибок, просто в этом файле-примере этого не было (теперь есть). А добавив в код 2 строки, будут обрабатываться и такие ситуации... (причем, добавление этих строк вообще никак не скажется на быстродействии)
Вроди бы общаемся на одном языке, но вы меня не понимаете (или делаете вид)... Я вам объяснил и показал в своем коде, что нет смысла тратить время и ресурсы на проверку и наращивание массива в цикле, если мы МОЖЕМ СРАЗУ УЗНАТЬ ЕГО РАЗМЕР. Тем более, что данный случай, позволяет реализовать алгоритм вообще БЕЗ ЕДИНОЙ проверки каких-либо условий (см. мой код) Я не пытался доказать, что мой алгоритм хороший, а ваш - плохой (а по-сути, у нас просто разные реализации, практически, одного алгоритма ), я лишь пытался вам объяснить, что оптимизировав свой код (убрав из циклов "лишние" действия), вы сделаете его еще быстрее! Хотя он и так достаточно быстрый и при некоторых условиях догоняет и даже обгоняет мой! (про "узкие места" в моем коде я знаю - могу исправить, но попозже...)
Ну, да, при отмене вываливалась ошибка, но косяк же был не в моем коде, а в процедуре "ВнешнийВид"... (исправил) И вообще, существование листа "ППСС" логичнее проверять ДО формирования плана перемещений, а иначе, какой смысл его формировать, если в конце пользователь откажется от удаления листа...
А такой ситуации быть не должно, т.к. я ему еще изначально делал выбор из списка (для удобства) и подсветку некоторых возможных ошибок, просто в этом файле-примере этого не было (теперь есть). А добавив в код 2 строки, будут обрабатываться и такие ситуации... (причем, добавление этих строк вообще никак не скажется на быстродействии)KSV
У нас с Вами разные подходы: Вы сделали код, чисто в рамках поставленной задачи, я немного расширил эти рамки, заложив возможность к более простому расширению функционала (в мою систему проще вставить дополнительные условия и проверки). Просто я считаю, что не надо надеяться, что пользователь всегда будет следовать раз установленным правилам, и стараюсь заложить тот самый "запас прочности", причём, не только в формате данных, но и в их анализе. Ещё я не люблю слепо следовать "голым" возможностям Excel, что подтверждается:
У нас с Вами разные подходы: Вы сделали код, чисто в рамках поставленной задачи, я немного расширил эти рамки, заложив возможность к более простому расширению функционала (в мою систему проще вставить дополнительные условия и проверки). Просто я считаю, что не надо надеяться, что пользователь всегда будет следовать раз установленным правилам, и стараюсь заложить тот самый "запас прочности", причём, не только в формате данных, но и в их анализе. Ещё я не люблю слепо следовать "голым" возможностям Excel, что подтверждается:
Спасибо Всем участникам обсуждения темы, благодаря Вам программа полностью отработана и вставлена в основную программу, работает удачно. Отдельно спасибо за Внимание к нестандартным ситуациям типа "Закрытие окна", в основной программе данная ошибка исправлена.
Спасибо Всем участникам обсуждения темы, благодаря Вам программа полностью отработана и вставлена в основную программу, работает удачно. Отдельно спасибо за Внимание к нестандартным ситуациям типа "Закрытие окна", в основной программе данная ошибка исправлена.Sashagor1982
Сообщение отредактировал Sashagor1982 - Четверг, 21.05.2015, 21:22