Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Excel VBA (часть 3)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214

Открыть новую тему     Написать ответ в эту тему

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

 
 
Обсуждаем вопросы только по Excel VBA
(программирование макросов, скриптов, пользовательских функций и т.п.).
Приветствуются ссылки на ресурсы и справочную литературу по теме.
 
Вопросы по работе с MS Excel, не относящиеся к программированию, задаем в теме Excel FAQ

 
Обратите внимание, этот топик для помощи в изучении и использовании VBA. Посему запросы типа "Напишите мне такой-то макрос, я VBA не знаю и знать не хочу" не приветствуются.
Древняя мудрость: "Накорми голодного рыбой и он погибнет, научи его ловить рыбу и ты спасешь его."(R)
 
Предыдущие ветки топика: Часть 1, Часть 2
 
Информация общего характера:
  • Список соответствия имен функций в английской и русской версиях Excel
  • Описание Microsoft Excel File Format (eng.)
     
    Рекомендации:
    Если у Вас есть проблема, не решаемая стандартными средствами Excel (об этом можно уточнить здесь) или требующая автоматизации, попробуйте для начала записать макрос самим Excel через меню Сервис (Tools) - Макрос (Macro) - Начать запись (Record New Macro). Подробнее здесь. В большинстве случаев получившийся код (Сервис-Макрос-Макросы-Изменить) Вас не удовлетворит, но подскажет, какие объекты-методы-свойства использовать.  
    Другой Ваш помощник - Просмотр объектов (Object Browser). Ну и встроення помощь (F1), естественно.
     
    Если Вы в тупике, покажите Ваш код (или часть кода) здесь.  Если вылазит ошибка, цитируйте ее полностью. Если код слишком большой, используйте тeг [more].
    Используйте отладчик - Breakpoints (F9), Watches (Shift-F9), Steps (F8 и др.) Сильно облегчает поиск ошибок.

     
    Рекомендуется к прочтению:
  • Первые шаги с Excel VBA
  • Excel VBA: Приёмы программирования
  • WinApi. Лекция из курса "Основы офисного программирования и язык VBA" (для продвинутых)
  • Daily Dose of Excel (eng.) - тематический блог: советы по работе с Excel и прочие материалы
  • Excel Macros & Excel VBA Code Tips, Tricks (eng.) - советы, трюки и уловки
  • Mr. Excel (forum) (eng.) - весьма оживленный форум по Excel&VBA.
  • Приемы, хитрости, трюки и нюансы работы в Microsoft Excel - сайт "Планета Excel", целиком посвященный Excel и всему, что с ним связано.
  • Microsoft Excel: Таблицы и VBA. Справочник. Вопросы и Ответы. Советы. Примеры.  
     
    Родственные топики:
  • Вопросы по работе с MS Excel - Excel FAQ - часть 1, часть 2, часть 3
  • Технические проблемы с MS Office 2003 или Office XP.
  • Word VBA все вопросы по Word VBA туда
  • Access все вопросы по программированию в Access туда
  • Книжульки по VBA - книги по программированию с использованием VBA
     
    Конкретные вопросы:
    Форма-заставка
    Как запустить макрос при изменении положения курсора или значения ячейки
  • Пример 1
  • Пример 2
  • Пример 3 (проверка области)
  • Пример 4
  • Пример 5
    Зацикливание в функции Change или SelectionChange
     
    Ранжирование без пробелов (макрос включает функции сортировки массива и удаления дубликатов, работает и в Excel 2007)
  • под Office 97
     
    Добавление в главное меню своего пункта, ассоциированного с макросом
    Создание ярлыка на рабочем столе
    Снятие защиты листа при забытом пароле
    Смена раскладки клавиатуры
    Скролл формы колесом прокрутки мыши
    Оптимизация кода по быстродействию использованием массивов
    Найти "чужое" окно и нажать в нем кнопку (вписать текст в текстовое поле)
    Работа с UNICODE-символами в VBA: запись, чтение из ячейки, перевод в ASС и обратно
    Как программно подключить дополнительные библиотеки (например, "Microsoft Scripting Runtime" или "Microsoft ActiveX Data Objects 2.8 Library) через References
     
    Перечень основных ColorIndex'ов из MSDN
     

    Смежные темы:
    Программы » Microsoft Office 2019 & 365 | 2016 | 2013 | 2010 | 2007 | 2003
    Программы » OneNote | Outlook 2013 & 2016 & 2019 | Outlook 2010 | Microsoft Mathematics & Math Solver
    Программы » Word FAQ | Excel FAQ | Access FAQ
    Прикладное программирование » Word VBA | Access VBA  
    Андеграунд » Microsoft Office 2019 | 2016 | 2013 | 2010 | 2007 | 2003
    Андеграунд » OneNote | Visio | SharePoint Server | Project Server | Exchange Server
    Андеграунд » Надстройки (add-ins) и коммерческие макросы Excel
    Андеграунд » Самостоятельная сборка дистрибутивов Оffice 2007/2010/2013/2016 | MUI для Office 2007

  • Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 10:16 11-01-2010 | Исправлено: ALeXkRU, 16:42 03-08-2021
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65
    Попробуй после перыой разборки по столбцам и перед второй вставкой сэмулировать разборку в другом формате (с другим разделителем, к примеру), чтобы Ексель его запомнил :)
     
    Или разбирай ве сразу, кучей. Но память ему все равно надо будет перед этим отбить :)

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 22:37 09-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Попробуй после перыой разборки по столбцам и перед второй вставкой сэмулировать разборку в другом формате (с другим разделителем, к примеру), чтобы Ексель его запомнил  

    Использование другого формата разборки ничего не сбрасывает. Получилось так:  
    берём  некую не пустую ячейку, делаем по ней разборку по столбцам с каким-нибудь жутким OtherChar, которого заведомо не будет в тексте, что будем потом разбирать.  
    Это частично решает проблему. Правда, есть шанс, что попадётся буфер с таким специфическим символом и, как следствие, при разборе вылетит ошибка.
    Такое вот почёсывание левого уха правой ногой по милости MS.
    Наверное, есть какой-нибудь способ занулить данные в классе, ну забыли они это сделать, или оставили специально для "удобства" пользователей.

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 00:39 10-08-2011 | Исправлено: mp65, 00:43 10-08-2011
    flexoleonhart

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Добрый день.
     
    Есть файл excel с "только для чтения" для создания заявок (либо только для выгрузки для знающих пароль). У большинства сотрудников он работает нормально, однако у некоторых возникает ошибка "Гы гы гы..." (это не стеб - в коде есть эта ошибка). Может кто подсказать, что именно ее может вызывать, если настройки у всех одинаковые, а ошибка может возникать у случайного сотрудника (хотя есть люди у которых она постоянно).
    p.s. я пытался логически прийти к проблеме,но сей язык прог-я я не знаю... поэтому очень надеюсь на любую помощь...
    собсно код

    Всего записей: 4 | Зарегистр. 21-12-2009 | Отправлено: 17:16 12-08-2011 | Исправлено: flexoleonhart, 17:44 12-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    flexoleonhart, лучше под тег 'more' положить код, а не под коврик.
     
     
    Добавлено:
    flexoleonhart
    Ячейка B1 на листе данной даты в файле реестра за данный месяц - пустая.
    Надо поставить точку останова в этом месте и исследовать ситуацию в момент ее возникновения.

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 17:31 12-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Подскажите, плз, могу ли я используя функцию Win API  - SendMessage послать в стороннее приложение последовательности Ctrl-Shift-S, Alt-Q и т.д.? Если да, то как?
    Понятно, что можно использовать keybd_event, но для этого, как я понял, нужно активировать это внешнее приложение, а это нежелательно, т.к. не совсем понятно какое приложение в данный момент в ForeGround-е, кроме того, возникают проблемы с нормальным возвращением в активное в данный момент приложение.
    Опишу задачу несколько по другому. Есть таблица Excel и несколько внешних приложений, которые прямо или косвенно передают данные в эту таблицу. На основе этих получаемых данных коду VBA Excel нужно посылать в эти приложения последовательности нажатий на клавиши, причём, все эти посылки не должны приводить к изменениям экрана пользователя. Например, по ходу работы надо послать для обновления содержимого страницы F5 в Foogle Chrome, а этот момент активно совсем другое приложение и если сделать AppActivate "Google Chrome" будет совсем не гуд, это помешает работе.  

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 23:38 13-08-2011
    Johnson Finger



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65 - можете. только вызывать придется внешний обработчик vbs скриптов, на сколько я помню. По крайней мере я писал в макросе хекселя эмуляцию нажатия клавиш.

    Всего записей: 1177 | Зарегистр. 06-08-2006 | Отправлено: 20:59 14-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65
    Может совсем в другую сторону посмотреть - встроить InternetExplorer и работать с ним, как с объектом...

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 21:29 14-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Johnson Finger
    Цитата:
    mp65 - можете. только вызывать придется внешний обработчик vbs скриптов, на сколько я помню. По крайней мере я писал в макросе хекселя эмуляцию нажатия клавиш.
    Пока написал с keybd_event, приходится активировать внешнее приложение, а не просто посылать ему message, как-то это кривовато.
    Внешний обработчик  vbs скриптов, это для меня пока тёмный лес, может примерчик подкинете?
     
    asbo
    Цитата:
    mp65  
    Может совсем в другую сторону посмотреть - встроить InternetExplorer и работать с ним, как с объектом...
    Я думал об этом, позапускать из excel нужные приложения и использовать их PID-ы, но это неудобно, поскольку они могут быть в любой момент закрыты пользователем, а при необходимости заново запущены.  
    Я не до конца разобрался с последовательностью поиска доступа к объектам внешнего приложения
    ihWnd = FindWindow(...
        ihWnd = FindWindowEx(...
        ihWnd = FindWindowEx(...
        ...
    но, даже когда я найду объект и универсальный алгоритм поиска для моих случаев, всё равно не понятно, как здесь использовать sendmessage для посылки хоткеев.
     

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 23:18 14-08-2011 | Исправлено: mp65, 23:23 14-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65
    Нет-нет. Я имел ввиду подключение к проекту Microsoft Internet Controls (ieframe.dll)
    Dim oApp As SHDocVw.InternetExplorer
    Вот отсюда кратенькое обсуждение на днях было.
     
    Добавлено:
    Тогда можно управлять объектом напрямую, через его своиства и метиоды, а не с помощью клавиатуры или ее эмуляции.

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 09:06 15-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    asbo
    Цитата:
    Тогда можно управлять объектом напрямую, через его своиства и метиоды, а не с помощью клавиатуры или ее эмуляции.
    Дело в том, что мне нужно использовать объект, который не я создаю, а пользователь.  
    Обновление окна Google Chrome я привёл просто в качестве примера, есть ещё приложения, которыми надо управлять, но структуры объектов которых я не знаю, могу только посмотреть и догадаться о том, откуда считывать и как и что класть.
     

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 11:49 15-08-2011 | Исправлено: mp65, 11:51 15-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Есть массив неповторяющихся чисел. Надо составить из них возможные комбинации (пары), но только прямые. Прямые, как я это обозвал :), значит, что канают только 1-2, 1-3, 2-3, но не 2-1, 3-1 и 3-2. Ну, или наоборот. Т.е. или то, или другое.
     
    Вот, наваял. Вроде бы работает. Посмотрите, плз, свежим взглядом - не перемудрил ли я и вдруг чего-то не учел? Завтра отдавать надо в ответственную задачу... Буду признателен за критику или найденные ошибки.  
     
    Концепция такова - перемещаясь от элемента к элементу, составляем комбинации только со следующими (оставшимися) элементами, но не с предыдущими, т.к. при проходе предыдущих они в этот элемент ужЕ смотрели. Собственно парсер за звездами. Вот код

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 20:40 15-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Интересный эффект обнаружил, похоже, что iif отличается от if. Идентичные по сути конструкции выдают разные результаты при TickLotA(i)<>0 и VolSdAcAr(i)=0&
     If VolSdAcAr(i) <> 0& Then
           Worksheets("Bid-Ask").Cells(i, 19) = Abs(Worksheets("Bid-Ask").Cells(i, 17) /(VolSdAcAr(i) * TickLotA(i)))
      Else
            Worksheets("Bid-Ask").Cells(i, 19) = ""
      End If
    даёт, как и должно, ""
    а  
    Worksheets("Bid-Ask").Cells(i, 19) = IIf(VolSdAcAr(i) <> 0&, Abs(Worksheets("Bid-Ask").Cells(i, 17) / (VolSdAcAr(i) * TickLotA(i))), "")  
    генерирует ошибку Деление на ноль.
    Что за чудеса?

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 15:31 16-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65
    IIf считает сразу обе части - и true и false. Поэтому, когда VolSdAcAr(i) = 0& первая часть дает ошибку деления на ноль. Поэтому я ее (IIf) не люблю.
    Bid-Ask=Spread ;)
     
    Добавлено:
    Бзв - в хелпе слово в слово то же самое :))

    Цитата:
    Remarks: IIf always evaluates both truepart and falsepart, even though it returns only one of them. Because of this, you should watch for undesirable side effects. For example, if evaluating falsepart results in a division by zero error, an error occurs even if expr is True.

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 16:31 16-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    asbo
    пасиб, оптимизация, туды-т её в качель

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 17:30 16-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65, не за что.
     
    Забыл сказать, что и к Switch это тоже относится. Она тоже все что в ней находится сразу просчитывает. А у нее аргументов дофига может быть. Поэтому для задач, критичных по быстродействию (а это, похоже, твой случай :), не рекомендуются. Запись только делают лаконичнее и все, имо... Я вообще стараюсь даже не If, а только Select Case использовать.

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 17:46 16-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    asbo
    Да, спасибо еще раз. Я как раз хотел  разные варианты реализаций на быстродействие протестить
    Когда писал на C, там было как раз наоборот, всякие встроенные в оператор инструкции приводили к более оптимальному коду, поскольку компилятор пихал их в регистры.
     
    Протестил сейчас простые двузвенные if, select case  и iif
    получилось по времени:
    if - 1
    select case - 3.06
    iif - 4.74
     
    Так что, прощай iif в ответственных местах кода
     
    Добавлено:
    Сделал более корректный тестовый пример, чтобы вероятности попадания в ветвлении были равномерно распределены, получился несколько иной результат, но для 2х и 3х вариантов выбора if все же прилично эффективней по быстродействию.
     
    2 варианта выбора
    if- 1
    select case - 1.21
     
    3 варианта выбора
    if- 1
    select case - 1.7

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 18:10 16-08-2011 | Исправлено: mp65, 22:53 16-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65
    VBA в плане быстродействия не совсем однозначно себя ведет. Иногда заведомо более быстрый (на взгляд) код, более быстрый на тестах, считает медленнее на реальных данных, в реальной обвязке, чем "медленный".

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 19:19 16-08-2011
    SAS888

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65
    asbo прав. В VBA, для оптимизации времени выполнения кода, в каждом конкретном случае нужно применять различные методы для решения, казалось бы, одинаковых задач.
    Так, например, в случае с оператором If: если требуется провести несколько сравнений, то после выполнения условия потребуется вставлять оператор безусловного перехода на конец блока этих If-ов. Что есть не рационально и медленно. В то время, как оператор Select Case сравнивает до первого совпадения (остальные, следующие ниже, игнорирует). Поэтому, проводя тест на скорость, все будет зависеть от условий и требуемого результата. Нельзя однозначно утверждать, что If "быстрее", чем Select Case.
    Также, если, например, требуется проверить несколько условий, то существенно рациональнее использовать "кучу" вложенных If-ов, нежели применять And и Or в одном If-е. Т.к. в первом случае проверка будет происходить последовательно, до первого false. И если грамотно расставить порядок сравнений, то можно еще ускорить процесс. Во втором же случае, будут проверены все условия, затем применены все логические операции, и только после этого - результат.
    Еще совет по оптимизации скорости: Не используйте функции типа Left, Mid, Trim и т.п. без значка "$", т.к. они возвращают значение типа Variant. Обычные функции Left$ и Trim$ возвращают результат немедленно, без его неявного преобразования в Variant.

    Всего записей: 398 | Зарегистр. 31-10-2007 | Отправлено: 05:55 17-08-2011 | Исправлено: SAS888, 06:02 17-08-2011
    mp65

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    SAS888
    Есть такой замечательный конструктив, как ElseIf - он позволяет избежать операторов goto в большинстве случаев. По сути такой вложенный if должен быть эквивалентен Select Case, только его труднее читать.  
    Я согласен с тем, что select case быстро работает, но выигрывает он у if только на большом числе вариантов, как показывает экскремент , на коротких цепочках if работает быстрее.
     
    Спасибо за информацию о mid и trim!  
     
    asbo
    Вопрос не совсем по теме. Интересно, а какую версию MSOffice Вы используете? Я остановился на 2003, может быть это не совсем верный выбор в плане эффективности?
    Я обратил внимание, что 2003 использует только одно ядро процессора, по крайней мере это справедливо для исполнения кода VBA Excel.

    Всего записей: 38 | Зарегистр. 29-09-2005 | Отправлено: 10:45 17-08-2011 | Исправлено: mp65, 12:36 17-08-2011
    asbo

    BANNED
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mp65
    Я мирюсь с тем, что "на коротких цепочках" Select Case проигрывает - его читабельность, удобство редактирования, гибкость с лихвой перекрывают возможную медлительность. И то, она проявляется только на 10^5...7 итерациях.  
     
    А касательно GoTo - считается дурным тоном :) У меня он только в единственном случае возникает - On Error
     
    SAS888
    Спасибо за напоминание про $ в строковых ф-циях. Я постоянно забываю, млин... Уже в десяти местах себе писал и галки ставил - забываю :(
     
    Возвращаясь к нашей дискуссии начала года - я все никак не могу причесать-окультурить до конца код для сравнения быстродействия :) Когда-нибудь выложу :)
     
    А вот вопрос: что быстрее - явное или неявное приведение типов? У меня часто используются такие конструкции: -5 * True. Понятно, что канонически лучше приводить явно, но тогда снижается читабельность и компактность. А как с т.з. быстродействия? Все собираюсь померять, руки не доходят :)

    Всего записей: 1805 | Зарегистр. 03-10-2006 | Отправлено: 11:19 17-08-2011
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Excel VBA (часть 3)


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru