<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Форум программистов и сисадминов Киберфорум - Блоги - amd48</title>
		<link>https://www.cyberforum.ru/blogs/827613/</link>
		<description>КиберФорум - форум программистов, системных администраторов, администраторов баз данных, компьютерный форум, форум по электронике и бытовой технике, обсуждение софта. Бесплатная помощь в решении задач по программированию и наукам, решение проблем с компьютером, операционными системам</description>
		<language>ru</language>
		<lastBuildDate>Sat, 12 Sep 2026 12:01:48 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>https://www.cyberforum.ru//cyberstatic.net/images/misc/rss.jpg</url>
			<title>Форум программистов и сисадминов Киберфорум - Блоги - amd48</title>
			<link>https://www.cyberforum.ru/blogs/827613/</link>
		</image>
		<item>
			<title>Разбор и расшифровка XML-тикетов МДЛП</title>
			<link>https://www.cyberforum.ru/blogs/827613/6929.html</link>
			<pubDate>Wed, 20 Jan 2021 08:39:38 GMT</pubDate>
			<description>Если вы не знаете, что такое МДЛП (или честный знак), вам крупно повезло. 
А если знаете, то у вас...</description>
			<content:encoded><![CDATA[<div>Если вы не знаете, что такое МДЛП (или честный знак), вам крупно повезло.<br />
А если знаете, то у вас мог возникнуть вопрос, как понять (а главное - быстро объяснить аптекарю), что там за коды в тикете. Особенно, если поставщик накосячил с 15 ошибкой и разагрегирование сделает только к концу дня или завтра, а товар без ошибок уже надо продавать. Надо же понимать, с каким конкретно товаром придётся ждать, а какой уже можно продать. Да и просто во всём потоке этих XML-ок как-то разбираться.<br />
Короче, сваял я в Excel'е этакий парсер МДЛП-шных XML-ок. На опыте тех, что через нас уже проходили. Это схемы<br />
416<br />
601<br />
607<br />
10531<br />
10511<br />
701<br />
702<br />
913<br />
20521<br />
и тикет с action_id=&quot;200&quot;<br />
<br />
Открываем эту эксельку. На листе жмём кнопку &quot;загрузить из XML&quot;. На вопрос отвечаем, хотим ли мы продолжить загрузку на лист, или очистить его и начать загрузку заново.<br />
Процедура определяет код схемы и соответствующий алгоритм разбора. Данные загружаются на лист и выдаётся сообщение с деталями файла и номер схемы. В таблице коды форматируются в наглядном виде, отделив GTIN. А в отдельном столбце этот GTIN сопоставляется с реестром лекарств. Реестр выгружен в конце прошлого года. Взят он выгрузкой из ЛК МДЛП. Т.е. можно будет потом вручную очередной выгрузкой обновить его.<br />
<br />
Программулька эта очень даже сырая, использоваться может <b>на свой страх и риск</b>. Сюда я это поделие выложил больше для сохранности своего творчества. Обязательно надо просмотратривать сам XML-файл в каком-нибудь вьювере. Например в Internet Explorer'е, чтоб видеть примерное количество записей в нём и сколько записей загрузилось в эксельку. До сих пор даже по известным и часто употребимым схемам появляются сюрпризы - структура обрастает новыми подробностями, которые могут быть не учтены. К примеру на днях случилось такое:<br />
продажи по ККТ в МДЛП стали появляться с офигенной задержкой - не в момент продажи, а где-нибудь в 10 часов ночи. Причём несколько разных продаж оказываются в одном файле, но поделёнными на разные &quot;рецепты&quot;. Это тоже пришлось учесть.</div>

]]></content:encoded>
			<dc:creator>amd48</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/827613/6929.html</guid>
		</item>
		<item>
			<title>Генератор календарей в Excel</title>
			<link>https://www.cyberforum.ru/blogs/827613/6878.html</link>
			<pubDate>Thu, 17 Dec 2020 10:55:05 GMT</pubDate>
			<description>Когда-то давно баловался в VBA и сделал генератор календарей для экселя 2003 версии. Там была форма...</description>
			<content:encoded><![CDATA[<div>Когда-то давно баловался в VBA и сделал генератор календарей для экселя 2003 версии. Там была форма с кучей настроек. Всё серьёзно. А теперь (аж с 2007 года) у нас есть Ribbon, куда можно засунуть весь интерфейс. Почти.<br />
Ну и вот. Открываем файл Календарь.xlsm. Переходим на вкладку панели инструментов под названием &quot;Календарь&quot;<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6649&amp;d=1608200157" rel="Lightbox" id="attachment6649" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6649&amp;thumb=1&amp;d=1608200157" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Снимок.PNG
Просмотров: 255
Размер:	4.5 Кб
ID:	6649" style="margin: 5px" /></a><br />
Кнопки по порядку:<br />
- Создание календаря. Создаётся новая книга, в которой на листе заполняются ячейки и получается календарь<br />
- выбор года<br />
- Переключатель выбора направления чередования месяцев. Сверху вниз или слева направо. Рядом выпадающий список со схемой размещения месяцев. Картинками показан пример расположения. <br />
- Переключатель выбора направления чередований дней в месяце. Сверху вниз или слева направо.<br />
- Кнопки сохранения и загрузки стиля оформления календаря. В архиве кроме Календарь.xlsm есть ещё пара примеров этих самых стилей - xml-файлы. <br />
<br />
Стиль можно настроить так:<br />
<img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6650&amp;d=1608200564" border="0" alt="Название: Снимок2.PNG
Просмотров: 980

Размер: 6.1 Кб" style="margin: 5px" /><br />
ячейки с маркером примечания в правом верхнем углу - интерактивные. Если щёлкнуть по такой ячейке, откроется диалог настройки шрифта. Можно выбрать начертания шрифта и всё остальное. Размер шрифта рекомендую сильно не менять, т.к. размер ячеек на листе новой книги будет задан жёстко и адаптированным под шрифт от 9 до 12 пунктов. Конечно, можно шрифт задать любым, а ячейки потом растянуть или скукожить вручную - полностью на ваше усмотрение. Размер всего календаря при печати его на принтере вы можете задать стандартными средствами экселя - задавая размер листа, его масштаб, область печати прочее. Выбранный формат после нажатия на кнопку ОК применится ко всем соответствующим ячейкам в образце. Всего существует 6 блоков календаря: заголовок года, заголовок месяца, будние дни, субботы, воскресенья, праздники. Именно этот набор отформатированных блоков можно сохранить в файле стиля.<br />
Про праздники. Под образцом календаря есть столбец со списком праздничных дней. Его можно заполнить любыми датами в стандартом формате дат экселя. Год не важен. Важны только день и месяц. <br />
<br />
Когда всё настроили, нажимаем кнопку создания календаря, ждём несколько секунд и получаем готовый календарь<br />
<br />
В готовом календаре все эти блоки фиксируются на листе:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6651&amp;d=1608201706" rel="Lightbox" id="attachment6651" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6651&amp;thumb=1&amp;d=1608201706" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Снимок3.PNG
Просмотров: 1131
Размер:	12.0 Кб
ID:	6651" style="margin: 5px" /></a><br />
Можно одним кликом выбрать нужный блок и настроить конкретно его - заново отформатировать шрифт или сделать что-нибудь ещё. Например, 12 блоков месяцев названы отдельно друг от друга. Их всё тем же одним кликом можно выделять и двигать по листу. Например, так:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6652&amp;d=1608202166" rel="Lightbox" id="attachment6652" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6652&amp;thumb=1&amp;d=1608202166" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Снимок4.PNG
Просмотров: 1160
Размер:	99.0 Кб
ID:	6652" style="margin: 5px" /></a><br />
Тут уже, как ваша фантазия разыграется.</div>


<!-- attachments -->
	<div style="margin-top:10px">

		
		
		
		
			<fieldset class="fieldset">
				<legend>Вложения</legend>
				<table cellpadding="0" cellspacing="3" border="0">
				<tr>
	<td><img loading="lazy" decoding="async" class="inlineimg" src="http://www.cyberforum.ru//cyberstatic.net/images/attach/zip.gif" alt="Тип файла: zip" width="16" height="16" border="0" style="vertical-align:baseline" /></td>
	<td><a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6653&amp;d=1608202291">Календарь.zip</a> (204.8 Кб, 1274 просмотров)</td>
</tr>
				</table>
			</fieldset>
		

	</div>
<!-- / attachments -->
]]></content:encoded>
			<dc:creator>amd48</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/827613/6878.html</guid>
		</item>
		<item>
			<title>MS Access. Альтернативный SQL-редактор</title>
			<link>https://www.cyberforum.ru/blogs/827613/6650.html</link>
			<pubDate>Tue, 30 Jun 2020 08:37:20 GMT</pubDate>
			<description>Здесь https://www.cyberforum.ru/ms-access/thread1740201.html я размышлял вслух и спрашивал всякие...</description>
			<content:encoded><![CDATA[<div>Здесь <a href="https://www.cyberforum.ru/ms-access/thread1740201.html">https://www.cyberforum.ru/ms-a... 40201.html</a> я размышлял вслух и спрашивал всякие советы об этом своём творении. Решил сухой остаток перенести в блог. Он-то уже никуда не уплывёт.<br />
<br />
Кратко, что это такое и зачем.<br />
В MSA встроенный редактор запросов имеет много ограничений в использовании и интерфейс, не превосходящий возможностей notepad.exe. А после работы в серьёзных средах (PL/SQL Developer для Oracle или MS SQL Server Management Studio) MSA просто удручает. И вот, под этим впечатлением сделана попытка воспроизвести нечто подобное. В редакторе используется RTF-форматирование, которое стало доступно в MSA 2010. В 2003 и более ранних версиях он работать не будет. В приведённой теме можно найти его ещё не-RTF-версию.<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6320&amp;d=1593502351" rel="Lightbox" id="attachment6320" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6320&amp;thumb=1&amp;d=1593502351" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Безымянный.png
Просмотров: 657
Размер:	24.3 Кб
ID:	6320" style="margin: 5px" /></a><br />
Редактор может быть полезен тем, кто предпочитает писать запросы руками, а не мышкой в конструкторе. Особенно это касается вложенных запросов, с использованием UNION и прочих, где конструктор не годится.<br />
Редактор состоит из MSA-формы fSQLEditor и модуля mSQLEditor. Их можно импортировать в любую вашу базу и работать с её таблицами и запросами. В приложенной базе есть форма frmExportForm, позволяющая одним кликом экспортировать редактор в вашу БД. Редактор будет доступен даже mde-базах, где стандартная среда разработки отключена.<br />
Возможности:<br />
- зарезервированные SQL-слова переводятся к верхнему регистру и окрашиваются в синий цвет<br />
- зарезервированные VBA-слова переводятся к Регистру и окрашиваются в бирюзовый цвет. И те и другие слова перечислены в массивах sSQL и sVBA в процедуре ColorRTF модуля mSQLEditor. Я перечислил там всё, что смог вспомнить. Можете дополнить своими при желании<br />
- текстовые строки внутри кавычек и апострофов, а так же числа окрашиваются в красный цвет<br />
- строки, начинающиеся на &quot;--&quot; считаются комментариями и окрашиваются в зелёный цвет. По задумке эти строки перед выполнением отбрасываются. Не всегда срабатывает :(<br />
- исполнять можно весь текст запроса целиком (курсор ничего не выделяет) или только выделенный фрагмент. Клавишами Shift+F7.<br />
- подстановка имён таблиц и запросов текущей БД. Вызывается кликом ПКМ:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6321&amp;d=1593502351" rel="Lightbox" id="attachment6321" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6321&amp;thumb=1&amp;d=1593502351" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Безымянный1.png
Просмотров: 614
Размер:	24.6 Кб
ID:	6321" style="margin: 5px" /></a><br />
- подстановка имён полей после точки. Вызывается кликом ПКМ:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6322&amp;d=1593502351" rel="Lightbox" id="attachment6322" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6322&amp;thumb=1&amp;d=1593502351" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Безымянный2.png
Просмотров: 664
Размер:	26.2 Кб
ID:	6322" style="margin: 5px" /></a><br />
<br />
После выполнения запроса:<br />
- в нижней части формы выводится таблица с результатом запроса, если это SELECT.<br />
- на вкладке &quot;интерпретатор&quot; выводится отформатированный самим MSA запрос, если он синтаксически корректен. Это текст запроса &quot;qTemp&quot;, который создаётся каждый раз при выполнении запроса из редактора<br />
<br />
Навигатор по сохранённым запросам БД (кнопка &quot;запросы БД&quot; на форме):<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6323&amp;d=1593502351" rel="Lightbox" id="attachment6323" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6323&amp;thumb=1&amp;d=1593502351" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Безымянный3.png
Просмотров: 708
Размер:	19.1 Кб
ID:	6323" style="margin: 5px" /></a><br />
- Тип запроса отмечается соответствующей буквой:<br />
s - select<br />
t - TRANSFORM<br />
d - delete<br />
u - update<br />
i - insert<br />
c - create<br />
ↀ - union<br />
- в навигаторе можно сохранить интерпретированный запрос, добавив к нему текстовое описание, которое задаётся через свойства запроса.<br />
- можно открыть встроенный редактор запросов, если он доступен<br />
- любой текст, набранный в редакторе, можно сохранить на диск в текстовый файл с расширением sql (см. кнопки слева вверху формы). А потом открыть в редакторе. При этом файл может содержать несколько запросов и комментарии. Выполнять его содержимое вы, всё равно, будете только выделенными фрагментами<br />
<br />
<br />
Обновления<br />
20.07.2020<br />
Попытка сделать из редактора надстройку не удалась. Не видит она чужие источники данных (т.е. текущей БД).<br />
Из другого аналогичного редактора позаимствовал обработку ошибок. Теперь ошибки синтаксиса и прочие при попытке исполнения SQL-кода выводятся на вкладку интерпретатора</div>


<!-- attachments -->
	<div style="margin-top:10px">

		
		
		
		
			<fieldset class="fieldset">
				<legend>Вложения</legend>
				<table cellpadding="0" cellspacing="3" border="0">
				<tr>
	<td><img loading="lazy" decoding="async" class="inlineimg" src="http://www.cyberforum.ru//cyberstatic.net/images/attach/zip.gif" alt="Тип файла: zip" width="16" height="16" border="0" style="vertical-align:baseline" /></td>
	<td><a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6324&amp;d=1595589960">sql_editorRTF.zip</a> (294.7 Кб, 374 просмотров)</td>
</tr>
				</table>
			</fieldset>
		

	</div>
<!-- / attachments -->
]]></content:encoded>
			<dc:creator>amd48</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/827613/6650.html</guid>
		</item>
		<item>
			<title>Инструментарий VBA</title>
			<link>https://www.cyberforum.ru/blogs/827613/4278.html</link>
			<pubDate>Mon, 30 May 2016 11:35:43 GMT</pubDate>
			<description>Что-то сильно примелькались темы о проблемах, когда человек не может выявить ошибку самостоятельно....</description>
			<content:encoded><![CDATA[<div>Что-то сильно примелькались темы о проблемах, когда человек не может выявить ошибку самостоятельно. При том, что более опытные люди как-то эти ошибки выявляют же. <br />
Не знаю, как это делают другие, внимательно вчитываются в код или ещё как-то. У меня одним из средств решения проблем и даже написания нового кода служат стандартные средства отладки, встроенную в среду VBA.<br />
Разберём их все.<br />
Первое, что мы можем сделать в любой программе из состава MS Office - открыть редактор VBA. Самый быстрый способ, особенно для тех, кто это делает каждый раз, когда открывает базу акцесса, нажать сочетание клавиш Alt+F11. Это срабатывает всегда, скрыто ли у вас меню, риббон, окно базы данных, нет открытых форм. <br />
По всем окошкам редактора я сильно углубляться не буду. Перечислю те, которые нужны именно в написании и отладке кода.<br />
<br />
<b>Выпадающие списки объектов.</b><br />
Это не окно, но один из самых важных элементов среды. Когда мы пишем код, набрали название какого-нибудь объекта, поставили точку и хотим написать название его дочернего объекта или функцию, выпадает список:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3856&amp;d=1464597060" rel="Lightbox" id="attachment3856" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3856&amp;thumb=1&amp;d=1464597060" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 417
Размер:	6.3 Кб
ID:	3856" style="margin: 5px" /></a><br />
А вы знали, что его можно открыть в любой момент и на любом месте клавишами Ctrl+J? Зачем он нужен? В нём перечислено всё, что доступно в работе с объектом, стоящим перед точкой. Среда VBA контролирует синтаксис и всегда выводит только то, что реально можно использовать в данном участке кода. Только в особых избранных случаях можно использовать и то, чего в списке нет. Но эти случаи настолько редкие и экзотические... Таким образом мы всегда можем найти нужную нам функцию или свойство, о которых мы что-то отдалённо помнили или догадывались об их существовании, но вот убей - не вспомнишь, как оно точно звалось. Я постоянно действую именно так - набираю первое слово до точки или даже только первые буквы, а остальное нахожу в списке, ставлю точку, и начинаю листать список. Много случаев было, когда я нашёл интересные особенности объекта именно этим пролистыванием, не читая документации, не копаясь в справке и не обращаясь к гуглам-форумам. Так же полный список самих объектов и их возможностей всегда можно открыть клавишей F2<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3858&amp;d=1464597060" rel="Lightbox" id="attachment3858" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3858&amp;thumb=1&amp;d=1464597060" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 683
Размер:	16.0 Кб
ID:	3858" style="margin: 5px" /></a><br />
Здесь можно по части названия самого объекта, функции, свойства, константы найти любой элемент языка. Так мной было обнаружено множество возможностей VBA просто на заданную тему. Очень напоминает википедию, которую открываешь вопросом, какого цвета киви, а через два часа отлипаешь от статьи о пунической войне.<br />
<br />
<b>Всплывающая подсказка о синтаксисе</b><br />
Набираем название объекта или функции, вставляем пробел или точку и видим всплывающую подсказку:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3857&amp;d=1464597060" rel="Lightbox" id="attachment3857" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3857&amp;thumb=1&amp;d=1464597060" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 619
Размер:	3.9 Кб
ID:	3857" style="margin: 5px" /></a><br />
Она кратко описывает синтаксис написания кода для этого объекта. Жирным отмечается параметр, который мы должны описать прямо сейчас, согласно его порядковому положению. В данном случае на картинке это Prompt - текст сообщения. В квадратных скобках перечислены параметры, не обязательные для заполнения. Для некоторых из них даже указаны значения по-умолчанию. Например, стандартная кнопка у любого меседжбокса, даже, если не указать, какие кнопки должны быть - ОК. Такая константа там и указана - vbOKOnly. Что, если мы хотим выбрать другие кнопки? Если мы после текста сообщения поставим запятую, то выпадет список доступных констант для настройки кнопок. Мы их можем перечислить через знак плюса. Например сочетание констант <div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="154009585"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="154009585" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">MsgBox <span class="st0">&quot;текст сообщения&quot;</span>, vbAbortRetryIgnore <span class="sy0">+</span> vbDefaultButton2 <span class="sy0">+</span> vbExclamation, <span class="st0">&quot;заголовок</span></pre></td></tr></table></div></td></tr></tbody></table></div> даст нам такой вид (Title (заголовок сообщения) мы можем пропустить. Тогда будет подставлено название программы):<br />
<img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3859&amp;d=1464597060" border="0" alt="Название: 4.png
Просмотров: 1443

Размер: 4.8 Кб" style="margin: 5px" /><br />
Имеем: три кнопки - прервать, повтор, пропустить. Кнопка &quot;повтор&quot; выбрана заранее и если пользователь сразу нажмёт клавишу Пробел, то сработает эта кнопка. Ну и константа vbExclamation вывела нам иконку восклицания. <br />
К чему я это всё описываю вроде бы к самому банальному коду из разряда &quot;хэлоу, ворлд&quot;? А к тому, что если мы захотим изменить этот кусок кода, то могли бы заменить одну из констант, нажав те самые Ctrl+J. Но есть подвох - откроется список <i>всех </i>возможных констант и объектов языка, а не только те константы, которые можно употреблять в этом параметре меседжбокса. Как же быть? Просто. Удаляем запятую перед перечислением этих констант. Или ставим ещё один знак плюса после одной из имеющихся констант. И список выпадает опять. И он опять показывает только те константы, которые мы можем подставить, чтоб они работали. Таким образом, мы, очень слабо зная бэйсик и английский со словарём, можем писать целые программы, ни разу не заглянув в справку. Код сам подсказывает нам, что мы должны писать.<br />
<br />
<b>Окно немедленного выполнения команд Immediate</b><br />
Часто нам бывает нужно узнать результат вычисления какого-нибудь выражения или выполнить какую-то команду, не создавая специально для этого модуль. В акцессе, например, это может быть команда <br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="757713974"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="757713974" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">DoCmd<span class="sy0">.</span><span class="me1">SetWarnings</span> <span class="kw1">False</span></pre></td></tr></table></div></td></tr></tbody></table></div>для скрытия всех вопросов с подтверждением на запросы удаления, обновления и добавления записей. Куда писать эту команду? Открываем редактор VBA и нажимаем клавишу Ctrl+G. Откроется окошко Immediate. Если оно уже было открыто, курсор встанет в него и мы можем сразу набирать, что захотим. Если надо, к примеру, узнать ответ на извечный вопрос, то так и пишем: <div class="codeblock"><table class="vb"><thead><tr><td colspan="2" id="435518052"  class="head">Visual Basic</td></tr></thead><tbody><tr class="li1"><td><div id="435518052" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">? 2+2</pre></td></tr></table></div></td></tr></tbody></table></div>Нажимаем Enter и получаем ответ. Вопросительный знак перед командой требует вывести ответ в это же окошко. Если мы напишем <div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="190269340"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="190269340" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="sy0">?</span> <span class="kw7">MsgBox</span> <span class="br0">&#40;</span><span class="st0">&quot;текст сообщения&quot;</span>, vbAbortRetryIgnore <span class="sy0">+</span> vbDefaultButton2 <span class="sy0">+</span> vbExclamation, <span class="st0">&quot;заголовок&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>, то увидим описанный нами меседжбокс. Но, когда мы нажмём одну из его кнопок, то в окошке Immediate появится код этой кнопки. Т.е. результат работы этой &quot;программы&quot;. Кстати, здесь перечислять параметры меседжбокса надо в скобках, т.к. этот синтаксис используется в норме в таком виде:<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="169190387"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="169190387" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1"><span class="kw1">If</span> <span class="kw7">MsgBox</span><span class="br0">&#40;</span><span class="st0">&quot;текст сообщения&quot;</span>, vbAbortRetryIgnore <span class="sy0">+</span> vbDefaultButton2 <span class="sy0">+</span> vbExclamation, <span class="st0">&quot;заголовок&quot;</span><span class="br0">&#41;</span> <span class="sy0">=</span> vbIgnore <span class="kw1">Then</span>
&nbsp; &nbsp; MsgBox <span class="st0">&quot;меня все игнорируют&quot;</span>
<span class="kw1">End</span> <span class="kw1">If</span></pre></td></tr></table></div></td></tr></tbody></table></div>А ещё мы можем сделать наоборот. Писать программу в модуле, а результаты работы получать во временное место, невидимое пользователю - в это же окошко Immediate. Например в процедуре у нас есть цикл. Он что-то там делает и мы хотим узнать, что насчиталось в переменной <i>a </i>и какое значение имеет счётчик цикла после выхода из него:<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="59148909"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="59148909" style="height: 254px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Sub</span> НашаПроцедура<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">For</span> i <span class="sy0">=</span> <span class="nu0">0</span> <span class="kw1">To</span> <span class="nu0">3</span>
&nbsp; &nbsp; a <span class="sy0">=</span> a <span class="sy0">+</span> i
&nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> <span class="st0">&quot;итерация&quot;</span>, i, a
<span class="kw1">Next</span>
Debug<span class="sy0">.</span><span class="me1">Print</span> <span class="st0">&quot;итог&quot;</span>, i, a
<span class="kw1">End</span> <span class="kw1">Sub</span>
&nbsp;
результат:
итерация &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> 
итерация &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> 
итерация &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> 
итерация &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">6</span> 
итог &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">6</span></pre></td></tr></table></div></td></tr></tbody></table></div>Результат вывелся с помощью Debug.Print. Через запятые можно перечислять все переменные, которые нас интересуют - они выведутся с отступом через табулятор. Теперь мы знаем, что в VBA счётчик цикла после выхода из цикла имеет значение на единицу больше, чем последняя итерация и он не обнуляется. Иногда бывают ошибки, когда переменная i в программе используется дальше и забыли её обнулить. Таким образом мы можем проверять значения различных переменных после отработки процедуры.<br />
<br />
<b>Режим отладки</b><br />
Кстати, в общих модулях запустить любую процедуру можно прямо из кода. Т.е. для этого не надо писать где-то ещё &quot;Call НашаПроцедура&quot; (Call нагляднее - понятно, что это написанная нами процедура). Мы просто ставим курсор в любом месте кода процедуры и нажимаем клавишу F5 (а если имеем дело с формой или отчётом, то запустим их работу) или кнопку &quot;воспроизведения&quot;<br />
<img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3861&amp;d=1464601287" border="0" alt="Название: 5.png
Просмотров: 1524

Размер: 653 байт" style="margin: 5px" /><br />
Запустим вот такой глупый код:<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="492761932"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="492761932" style="height: 142px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Sub</span> НашаПроцедура<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">For</span> i <span class="sy0">=</span> <span class="nu0">3</span> <span class="kw1">To</span> <span class="nu0">0</span> <span class="kw1">Step</span> <span class="sy0">-</span><span class="nu0">1</span>
&nbsp; &nbsp; a <span class="sy0">=</span> a <span class="sy0">+</span> i
&nbsp; &nbsp; a <span class="sy0">=</span> a <span class="sy0">/</span> i
&nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> a
<span class="kw1">Next</span>
<span class="kw1">End</span> <span class="kw1">Sub</span></pre></td></tr></table></div></td></tr></tbody></table></div>Наша программа немного поработала, а потом выдала сообщение об ошибке. <br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3862&amp;d=1464601568" rel="Lightbox" id="attachment3862" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3862&amp;thumb=1&amp;d=1464601568" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 6.png
Просмотров: 605
Размер:	4.9 Кб
ID:	3862" style="margin: 5px" /></a><br />
Не будем его сразу закрывать и бежать на форум с воплем &quot;ваш пример не работает выдаёт какую-то ашипку&quot;. Посмотрим, что нам предлагает сделать сам VBA. Run-time error - это код ошибки. Его можно использовать в таком обработчике ошибок:<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="455964088"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="455964088" style="height: 254px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Sub</span> НашаПроцедура<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">On</span> <span class="kw1">Error</span> <span class="kw1">GoTo</span> ErrorHandler
<span class="kw1">For</span> i <span class="sy0">=</span> <span class="nu0">3</span> <span class="kw1">To</span> <span class="nu0">0</span> <span class="kw1">Step</span> <span class="sy0">-</span><span class="nu0">1</span>
&nbsp; &nbsp; a <span class="sy0">=</span> a <span class="sy0">+</span> i
&nbsp; &nbsp; a <span class="sy0">=</span> a <span class="sy0">/</span> i
&nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> a
<span class="kw1">Next</span>
<span class="kw1">Exit</span> <span class="kw1">Sub</span>
ErrorHandler:
<span class="kw1">Select</span> <span class="kw1">Case</span> Err<span class="sy0">.</span><span class="me1">Number</span>
<span class="kw1">Case</span> <span class="nu0">11</span>: MsgBox <span class="st0">&quot;На ноль делить нельзя&quot;</span>, vbCritical
<span class="kw1">Case</span> <span class="kw1">Else</span>: MsgBox Err<span class="sy0">.</span><span class="me1">Description</span>, vbCritical, <span class="st0">&quot;Код ошибки: &quot;</span> <span class="sy0">&amp;</span> Err<span class="sy0">.</span><span class="me1">Number</span>
<span class="kw1">End</span> <span class="kw1">Select</span>
<span class="kw1">End</span> <span class="kw1">Sub</span></pre></td></tr></table></div></td></tr></tbody></table></div>On Error GoTo ErrorHandler - инструкция о том, что в случае ошибки программа должна перейти к метке ErrorHandler. Сама метка в коде обозначается её названием и двоеточием. Стоит она после строки Exit Sub - это ещё не конец процедуры, но без меток программа туда не попадёт. Затем начинается перебор всех кодов ошибок, которые в ходе работы процедуры могут возникнуть - Select Case Err.Number. Пока нам известен только код 11 - мы его увидели в сообщении. ДЛя него мы и сделаем своё грозное предупреждение, что так делать нельзя<br />
<div class="codeblock"><table class="vb"><thead><tr><td colspan="2" id="130204599"  class="head">Visual Basic</td></tr></thead><tbody><tr class="li1"><td><div id="130204599" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw3">Case</span> 11: MsgBox <span class="st0">&quot;На ноль делить нельзя&quot;</span>, vbCritical</pre></td></tr></table></div></td></tr></tbody></table></div>Двоеточие после &quot;Case 11&quot; - это не метка, а сокращение написания - чтоб можно было очередную команду написать в этой же строчке. Вот такой код короче на одну строчку за счёт того, что &quot;a = a / i&quot; написано в одной строчке с &quot;Else&quot; :)<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="439874937"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="439874937" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="kw1">If</span> i <span class="sy0">=</span> <span class="nu0">0</span> <span class="kw1">Then</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a <span class="sy0">=</span> <span class="nu0">0</span>
&nbsp; &nbsp; <span class="kw1">Else</span>: &nbsp; a <span class="sy0">=</span> a <span class="sy0">/</span> i
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span></pre></td></tr></table></div></td></tr></tbody></table></div>Продолжим рассматривать обработчик. Строчка<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="777316592"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="777316592" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Case</span> <span class="kw1">Else</span>: MsgBox Err<span class="sy0">.</span><span class="me1">Description</span>, vbCritical, <span class="st0">&quot;Код ошибки: &quot;</span> <span class="sy0">&amp;</span> Err<span class="sy0">.</span><span class="me1">Number</span></pre></td></tr></table></div></td></tr></tbody></table></div>выводит не менее грозное сообщение об ошибке, но текст с описанием ошибки берётся из самого VBA - из свойства Err.Description. Если MS Office руссифицированный, то большинство сообщений об ошибках будет написано по-русски. Таким образом и ошибку мы обработаем так, чтоб пользователь не гадал, как на неё реагировать. И, если дополнительно постараться, то можно в программе реализовать правильные решения в таких ситуациях. Но эта тема для отдельного разговора.<br />
Если вы точно уверены, что программа даже с ошибкой будет работать правильно и ошибочное выражение можно смело пропустить, то вместо &quot;On Error GoTo ErrorHandler&quot; можно написать &quot;On Error Resume Next&quot;. А если во время отладки хотите проверить конкретный участок кода, то прямо перед ним добавить &quot;On Error GoTo 0&quot;. Тогда в случае ошибки появится обычное отладочное сообщение, как на картинке выше. Оно проигнорирует все предыдущие инструкции на счёт реакции на ошибку. Это бывает удобно, если отладчик уже написан, но закралась ещё одна ошибка, о которой мы ещё ничего не знаем.<br />
На всякий случай, чтоб не потерять мысль:<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="337603723"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="337603723" style="height: 334px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Sub</span> НашаПроцедура<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">On</span> <span class="kw1">Error</span> <span class="kw1">GoTo</span> ErrorHandler
<span class="kw1">For</span> i <span class="sy0">=</span> <span class="nu0">3</span> <span class="kw1">To</span> <span class="nu0">0</span> <span class="kw1">Step</span> <span class="sy0">-</span><span class="nu0">1</span>
&nbsp; &nbsp; a <span class="sy0">=</span> a <span class="sy0">+</span> i
&nbsp; &nbsp; <span class="kw1">On</span> <span class="kw1">Error</span> <span class="kw1">GoTo</span> <span class="nu0">0</span>
&nbsp; &nbsp; a <span class="sy0">=</span> a <span class="sy0">/</span> i
&nbsp; &nbsp; <span class="kw1">If</span> i <span class="sy0">=</span> <span class="nu0">0</span> <span class="kw1">Then</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a <span class="sy0">=</span> <span class="nu0">0</span>
&nbsp; &nbsp; <span class="kw1">Else</span>: &nbsp; a <span class="sy0">=</span> a <span class="sy0">/</span> i
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span>
&nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> a
<span class="kw1">Next</span>
<span class="kw1">Exit</span> <span class="kw1">Sub</span>
ErrorHandler:
<span class="kw1">Select</span> <span class="kw1">Case</span> Err<span class="sy0">.</span><span class="me1">Number</span>
<span class="kw1">Case</span> <span class="nu0">11</span>: MsgBox <span class="st0">&quot;На ноль делить нельзя&quot;</span>, vbCritical
<span class="kw1">Case</span> <span class="kw1">Else</span>: MsgBox Err<span class="sy0">.</span><span class="me1">Description</span>, vbCritical, <span class="st0">&quot;Код ошибки: &quot;</span> <span class="sy0">&amp;</span> Err<span class="sy0">.</span><span class="me1">Number</span>
<span class="kw1">End</span> <span class="kw1">Select</span>
<span class="kw1">End</span> <span class="kw1">Sub</span></pre></td></tr></table></div></td></tr></tbody></table></div>
				   </div>
			   </div><br />
Так. Что-то я отвлёкся на обработчик ошибки. У нас же было своё - отладочное - сообщение. Продолжим его рассматривать. <br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3862&amp;d=1464601568" rel="Lightbox" id="attachment3862" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3862&amp;thumb=1&amp;d=1464601568" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 6.png
Просмотров: 605
Размер:	4.9 Кб
ID:	3862" style="margin: 5px" /></a><br />
А дальше у нас несколько кнопок. <br />
<b>Кнопка &quot;Continue&quot;</b><br />
В сообщения об ошибках она заблокирована, т.к. ошибку устранять нам, а пока мы с ней не разберёмся, программа продолжать работать не будет. Но есть случаи, когда можно и продолжить. А эти случаи самые что ни наесть отладочные. Допустим, программа зашла в бесконечный цикл:<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="649252267"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="649252267" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Sub</span> Бесконечность<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">Dim</span> i <span class="kw1">As</span> <span class="kw2">Integer</span>
<span class="kw1">While</span> i <span class="sy0">=</span> <span class="nu0">0</span>
&nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> i
<span class="kw1">Wend</span>
<span class="kw1">End</span> <span class="kw1">Sub</span></pre></td></tr></table></div></td></tr></tbody></table></div>Переменная i у нас самого начала была равна нулю и в ходе выполнения цикла с ней ничего не происходит, только выводится её значение. Но цикл никак не может завершиться. Что же делать, если мы запустили такую программу? Перезагружать компьютер, лезть в диспетчер задач? Не обязательно. В любой момент нажимаем клавиши Ctrl+Break. И вот в этом случае у нас и выходит отладочное сообщение, на котором кнопка Continue в этот раз доступна. И нажав её, мы можем опять созерцать работу бесконечности. Но остановить бесконечность нам удалось только потому, что компьютер у нас никогда из неё по своей воле не выйдет. А если программа будет чуть покороче бесконечности или компьютер достаточно быстрый, то мы не успеем уловить этот момент и прервать выполнение программы. А ведь иногда надо это сделать. Для этого у нас есть парочка способов.<br />
<br />
<b>Команда Stop</b><br />
Эту команду мы можем вставить в промежуток между любыми строчками нашего кода. Когда программа в ходе своей работы наткнётся на неё, сообщение мы не увидим, но программа остановится (Странно. Были случаи, когда и сообщение появлялось тоже). Немного модифицируем и запустим нашу бесконечность:<br />
<img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3863&amp;d=1464605338" border="0" alt="Название: 7.png
Просмотров: 1241

Размер: 4.5 Кб" style="margin: 5px" /><br />
Когда переменная <i>a</i> достигает значения 100, программа останавливается на команде Stop. Сама она выделяется жёлтым маркером, а в левом поле редактора напротив неё стоит жёлтая стрелка - маркер перехода. Мы можем схватить эту стрелку мышкой и переставить в любую другую строчку кода, затем опять нажать клавишу F5 и программа продолжит свою работу с этого места. <font color="DarkSlateGray">Кстати, из-за того, что Stop я разместил в одной строке с условием &quot;If a = 100 Then&quot;, переставить этот маркер перехода на само условие стало сложнее. Поэтому, хоть такой код и выглядит комактнее, отлаживать его с помощью стопов чуточку сложнее.</font> Впрочем и на команде Stop можно нажать клавишу F5. Но это как-то бессмысленно. Как это можно использовать? Можно нажать другую клавишу - F8. Она продолжает только одну команду в коде. Таким образом мы можем вести программу по шагам. Выполнять очередной шаг и смотреть на результаты. Можно сразу всю программу запустить в пошаговом режиме. Вместо F5 с самого начала нажать F8 и следить за каждым её шагом.<br />
<br />
<b>Точка останова</b><br />
У команды Stop есть одновременно и достоинство и недостаток. Достоинство в том, что с его помощью мы можем оставить этакую закладку. Мы можем сохранить программу в таком виде, запустить её через некоторое время, и программа опять остановится в этом же месте, как бы напоминая нам, что в этом месте надо было сделать ещё что-то важное. Главное, не забыть о ней, отдавая программу пользователю. В этом и кроется её недостаток - о ней надо помнить, чтоб потом убрать из кода. А чтоб отладить программу и не оставлять следов этого, можно использовать точки останова. Они не сохраняются, если программу закрыть, что тоже удобно. Поставить её можно, щёлкнув в левое поле редактора напротив нужной строчки или нажать клавишу F9<br />
<img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3864&amp;d=1464606779" border="0" alt="Название: 8.png
Просмотров: 1405

Размер: 4.9 Кб" style="margin: 5px" /><br />
На картинке опять эта ситуация из-за &quot;сокращения&quot; кода, когда не понятно, какая из команд будет выполняться следующей - проверка условия или команда Stop. <br />
Опять я отвлёкся от нашего отладочного сообщения. Но на самом деле, не сильно. Дело в том, что в случае ошибки кнопка &quot;Debug&quot; в нём возвращает нас в код, как при использовании стопов. И в этот раз мы уже можем маркер перехода переставить в другую строчку кода, обойдя ошибочную команду, или даже иногда исправить текст кода, пока программа стоит на паузе, а потом опять её продолжить.<br />
<br />
<b>Окно Watches</b><br />
Останавливать программу мы научились. Пропустить команды можем. Можем посмотреть значения некоторых переменных. Но делается это как-то сложно. Надо много писать, смотреть в какие-то окна, не всегда понимая, значения каких именно переменных нам туда написало. А ведь у нас в распоряжении есть ещё одно удобное окошко - Watches. Никаких специальных клавиш для него не заведено. Потому, что его обычно размещают в удобном месте экрана и больше не трогают. Открыть его можно через меню View - Watch Window:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3865&amp;d=1464607496" rel="Lightbox" id="attachment3865" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3865&amp;thumb=1&amp;d=1464607496" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 9.png
Просмотров: 512
Размер:	16.1 Кб
ID:	3865" style="margin: 5px" /></a><br />
Изначально это окошко всегда пустое, а через него мы можем отслеживать состояние <i>любого </i>объекта среды программирования (в акцессе через него мы можем следить ещё и за и за формами и отчётами). Есть несколько способов, как это сделать. Если у нас в коде программы уже написаны какие-то объекты, то мы их можем:<br />
1. перетащить мышкой в окно Watches<br />
2. выделив название и нажав правой кнопкой мыши, выбрать в меню команду &quot;Add Watch&quot;<br />
3. в окне Watches в свободном пространстве щёлкнуть правой кнопкой мышки, выбрать команду &quot;Add Watch&quot; и в поле &quot;Expression&quot; набрать любое выражение. Например, &quot;2+2&quot;. После добавления увидим результат выражения в столбце Value. <br />
Кроме того, в диалоге &quot;Add Watch&quot; можно задать параметры слежки<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3866&amp;d=1464608670" rel="Lightbox" id="attachment3866" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3866&amp;thumb=1&amp;d=1464608670" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 10.png
Просмотров: 595
Размер:	8.7 Кб
ID:	3866" style="margin: 5px" /></a><br />
Этим же способом можно настроить слежку за теми объектами, которые мы добавляли из кода. <br />
Мы можем этим способом остановить нашу бесконечность, когда переменная <i>a</i> будет равна сотне. Для этого добавляем в Watches не саму переменную, а выражение &quot;a = 100&quot;, а в настройках слежки выбираем пункт &quot;Break When Value Is True&quot;. Т.е. остановить программу, когда выражение &quot;a = 100&quot; станет истиной. Когда программа стоит на паузе, мы можем руками исправлять значение переменных, которые добавлены в окно Watches. Щёлкаем по имеющемуся значению в столбце Value и пишем туда нужное нам значение. Например, сделаем <i>a</i> равной 99. Напоминает хирургическую операцию под наркозом, неправда ли?<br />
Мы так же можем во время паузы выполнения программы размещать в Watches другие переменные и даже формы со всеми их кнопками, полями и вложенными формами. <br />
Изобразим пример таких манипуляций.<br />
Допустим, у нас есть некая Таблица1 с полем Поле1. На основе этой таблицы имеем форму Form1 и кнопку для перехода к следующей записи. Код этой кнопки будет такой:<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="46758673"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="46758673" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Private</span> <span class="kw1">Sub</span> Кнопка<span class="nu0">2</span>_Click<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; DoCmd<span class="sy0">.</span><span class="me1">GoToRecord</span> , , acNext
&nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> <span class="kw1">Me</span><span class="sy0">.</span>Поле<span class="nu0">1</span>
&nbsp; &nbsp; <span class="kw1">Stop</span>
<span class="kw1">End</span> <span class="kw1">Sub</span></pre></td></tr></table></div></td></tr></tbody></table></div>Сначала процедура переходит в следующую запись, затем выводит для нас значение Поле1 в этой записи, а потом останавливается программа. И вот теперь мы можем посмотреть кое-что интересное. Выделяем слово Me (это ссылка на объект Form1 в контексте её своей собственной работы) и перетаскиваем в окно Watches. Там это слово появляется не просто так, а с плюсиком слева от себя. Если его нажать, то развернётся боооооольшооооой список всех свойств формы. <br />
Там мы можем в конце списка найти перечисление всех элементов на форме &quot;Item 1&quot;, &quot;Item 2&quot; и т.д. Один из них - Поле1, другой - наша кнопка. Они имеют свои большие списки. <br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3867&amp;d=1464612517" rel="Lightbox" id="attachment3867" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3867&amp;thumb=1&amp;d=1464612517" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 11.png
Просмотров: 605
Размер:	12.9 Кб
ID:	3867" style="margin: 5px" /></a><br />
Если в окно Watches поместить выражение Me.Поле1, то мы сразу увидим свойства только этого элемента.<br />
Свойства элементов формы прямо здесь изменить мы не сможем, но просто посмотреть, что с ними происходит, пока программа стоит на паузе, можем. Очень часто и этого бывает достаточно. Да и просто много интересного о внутренностях нашей программы можно узнать. <br />
Вообще, во время паузы можно посмотреть значения свойств объектов и переменных прямо в коде, никуда их не вынося - просто наведя мышку на них. Но эти свойства должны быть в коде, чтоб на них можно было смотреть. А в окне Watches можно видеть и то, с чем мы в данный момент и не работаем.<br />
<br />
Прямо над <i>Watches Window</i> в меню можно открыть ещё одно окошко - <b>Locals</b>. По сути это почти такое же окошко, как и Watches, но охватывает только список переменных, которые мы используем в нашей процедуре и модуле. Но их не надо поштучно выносить в список, чтоб посмотреть на их значения. Правда, переменные из других модулей, даже если они объявлены Public, мы не увидим. <br />
<b>Шаги обхода</b><br />
Клавиши F5 и F8 я уже описал. Но у нас есть ещё несколько клавиш.<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3868&amp;d=1464613152" rel="Lightbox" id="attachment3868" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=3868&amp;thumb=1&amp;d=1464613152" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 12.png
Просмотров: 445
Размер:	12.2 Кб
ID:	3868" style="margin: 5px" /></a><br />
Посмотрим на таком примере.<br />
<div class="codeblock"><table class="vbnet"><thead><tr><td colspan="2" id="355653198"  class="head">VB.NET</td></tr></thead><tbody><tr class="li1"><td><div id="355653198" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="de1"><pre class="de1"><span class="kw1">Sub</span> Месяц<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">Dim</span> dt <span class="kw1">As</span> <span class="kw2">Date</span>
dt <span class="sy0">=</span> <span class="kw7">DateValue</span><span class="br0">&#40;</span><span class="st0">&quot;01/05/2016&quot;</span><span class="br0">&#41;</span>
<span class="kw1">While</span> <span class="kw7">Month</span><span class="br0">&#40;</span>dt<span class="br0">&#41;</span> <span class="sy0">=</span> <span class="nu0">5</span>
&nbsp; &nbsp; <span class="kw1">If</span> Выходной<span class="br0">&#40;</span>dt<span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw1">True</span> <span class="kw1">Then</span>
&nbsp; &nbsp; &nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> <span class="st0">&quot;выходной&quot;</span>, dt
&nbsp; &nbsp; <span class="kw1">Else</span>
&nbsp; &nbsp; &nbsp; &nbsp; Debug<span class="sy0">.</span><span class="me1">Print</span> <span class="st0">&quot;рабочий день&quot;</span>, dt
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span>
&nbsp; &nbsp; dt <span class="sy0">=</span> <span class="kw7">DateAdd</span><span class="br0">&#40;</span><span class="st0">&quot;d&quot;</span>, <span class="nu0">1</span>, dt<span class="br0">&#41;</span>
<span class="kw1">Wend</span>
<span class="kw1">End</span> <span class="kw1">Sub</span>
&nbsp;
<span class="kw1">Function</span> Выходной<span class="br0">&#40;</span>dDate <span class="kw1">As</span> <span class="kw2">Date</span><span class="br0">&#41;</span> <span class="kw1">As</span> <span class="kw2">Boolean</span>
<span class="kw1">Select</span> <span class="kw1">Case</span> <span class="kw7">Weekday</span><span class="br0">&#40;</span>dDate, vbMonday<span class="br0">&#41;</span>
<span class="kw1">Case</span> <span class="nu0">6</span>, <span class="nu0">7</span>
&nbsp; &nbsp; Выходной <span class="sy0">=</span> <span class="kw1">True</span>
<span class="kw1">Case</span> <span class="kw1">Else</span>
&nbsp; &nbsp; Выходной <span class="sy0">=</span> <span class="kw1">False</span>
<span class="kw1">End</span> <span class="kw1">Select</span>
<span class="kw1">End</span> <span class="kw1">Function</span></pre></td></tr></table></div></td></tr></tbody></table></div>Запускать будем процедуру &quot;Месяц&quot;. Она в цикле перебирает все дни мая 2016 года и запрашивает у функции &quot;Выходной&quot; - этот день выходной? Допустим, мы хотим по шагам проверить работу только процедуры. Мы уверены, что функция работает правильно и пошаговый проход займёт у нас лишнее время. В этом случае мы можем, доходя до строки &quot;<font face="Courier New">If Выходной(dt) = True Then</font>&quot;, нажимать не <b>F8</b>, а <b>Shift+F8</b> - перешагнуть. Т.е. просим VBA выполнить функцию, но не показывать нам, как она это делает. <br />
Но, если мы, всё таки, зашли в функцию и хотим из неё быстро выйти всё потому, что она нам не интересна, то мы можем нажать <b>Ctrl+Shift+F8</b> - выйти.<br />
<b>Ctrl+F8</b> - запустить до курсора. Мы можем поставить курсор в коде на несколько строчек позже текущего шага и перешагнуть через все строки, которые окажутся между ними. Это всё равно, что поставить на месте курсора точку останова и нажать F5.</div>

]]></content:encoded>
			<dc:creator>amd48</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/827613/4278.html</guid>
		</item>
	</channel>
</rss>
