<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=93310&amp;view=findpost&amp;p=700791</guid>
        <pubDate>Sat, 30 Apr 2005 15:58:02 +0000</pubDate>
        <title>Строковые функции</title>
        <link>https://forum.sources.ru/index.php?showtopic=93310&amp;view=findpost&amp;p=700791</link>
        <description><![CDATA[Old Bat: <span class="tag-font" data-value="Arial" style="font-family:Arial"><strong class='tag-b'>Используйте LEN() для проверки нулевой длины строк</strong><br>
<br>
Сравнение строки с нулем происходит значительно быстрее, чем при сравнении с &quot;&quot;. VBA хранит строки в формате BSTR, т.е. в начале каждой строки существует 4 байта, где хранится длина текущей строки. Таким образом, LEN() не вычисляет длину строки, а считывает уже существующее значение. К тому же пустую строку (&quot;&quot;) еще надо создать, на что и уходит часть времени.<br>
<br>
<strong class='tag-b'>Для инициализации строк вместо &quot;&quot; используйте константу vbNullString</strong><br>
<br>
Когда Вы пишете &quot;MyString = vbNullString&quot;<br>
VBA не создает новую строку, вместо этого он использует свой внутренний указатель на нее, что существенно экономит время.<br>
<br>
<strong class='tag-b'>Не увлекайтесь излишней конкатенацией</strong><br>
<br>
Операции конкатенации в VBA весьма медленны, так что имейте это в виду, собирая длинные строки из множества фрагментов.<br>
<br>
<strong class='tag-b'>Используйте IsCharAlphaNumeric вместо ASCII-значений</strong><br>
<br>
Если Вам приходится проверять, является ли некоторый символ буквенно-цифровым (то есть входит ли он в диапазон A-Z, a-z, А-Я, а-я, 0-9). – используйте API-функцию IsCharAlphaNumeric. Кроме того, можно воспользоваться еще одной похожей функцией Windows API, IsCharAlpha, определяющей, является ли символ с переданным ей кодом буквой. Дополнительным преимуществом функций Windows API является то, что они интернационализированы. Ведь если вам нужно, чтобы программа работала с текстом, написанным на разных языках, недостаточно сравнить код буквы с границами определенных диапазонов: вы рискуете пропустить те буквы, которые в эти диапазоны не входят. И наконец, функции Windows API работают быстрее функции сравнения кодов.<br>
<br>
Можем написать так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Const cFirstChar = 65</div><div class="code_line">Const cLastChar = 90</div><div class="code_line">Const cFirstDigit = 48 </div><div class="code_line">Const cLastDigit = 57</div><div class="code_line">&nbsp;</div><div class="code_line">intC = Asc(UCase(strC))</div><div class="code_line">If (intC = cFirstChar And _ </div><div class="code_line">intC &#60;= cLastChar) _ </div><div class="code_line">Or (intC &#62;= cFirstDigit And _ </div><div class="code_line">intC &#60;= cLastDigit) Then</div><div class="code_line">&nbsp;&nbsp;&#39; Это буква или цифра. </div><div class="code_line">&nbsp;&nbsp;&#39;Делаем то, что нужно в этом случае. </div><div class="code_line">End If</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
А можем так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Private Declare Function IsCharAlphaNumeric _</div><div class="code_line">&nbsp;Lib &quot;user32&quot; Alias &quot;IsCharAlphaNumericA&quot; _</div><div class="code_line">(ByVal cChar As Byte) As Long</div><div class="code_line">&#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39; &#39;</div><div class="code_line">If IsCharAlphaNumeric(Asc(strC)) Then</div><div class="code_line">&nbsp;&#39; Это буква или цифра.</div><div class="code_line">&nbsp;&#39; Делаем то, что нужно в этом случае. </div><div class="code_line">End If</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>Сравнивайте строки с помощью StrComp, <br>
не преобразуя их к верхнему регистру с помощью UCase</strong><br>
<br>
VBA сравнивает строки с учетом опции Option Compare. По умолчанию VBA использует опцию Option Compare Binary, при которой результаты сравнения зависят от регистра символов.В противном случае объявите  Option Compare Text в начале  модуля.<br>
Если необходимо указать способ сравнения на уровне отдельной процедуры, то используйте функцию StrComp. Она позволяет задать две строки и константу, указывающую, как их сравнивать: vbUseCompareOption (использовать текущую установку Option Compare), vbBinaryCompare (осуществлять сравнение с учетом регистра), vbTextCompare (сравнивать без учета регистра) или vbDatabaseCompare (использовать режим сравнения, заданный для базы данных). Функция StrComp возвращает 0, если строки равны, -1, если первая строка меньше второй, и +1, если первая строка больше второй. Для сравнения двух строк без учета регистра можно написать одну из двух строк кода:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">If UCase(strValuel) = UCase(strValue2) Then</div></ol></div></div></div></div><br>
или<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">If (StrCompCstrValuel, strvalue2, vbTextCompare) = 0 Then</div></ol></div></div></div></div><br>
Короткие строки быстрее обрабатываются функцией StrComp, однако при существенном увеличении их длины становится практически все равно, каким образом их сравнивать. <br>
<br>
<strong class='tag-b'>Используйте оператор LIKE, а не сравнивайте символы по отдельности</strong><br>
<br>
Допустим, требуется проверить значение некой переменной, состоящей из букв и цифр, стоящих в определенной последовательности: например - &quot;W5TGQ&quot;. Сделать это можно так: перебрать в цикле все символы строки и проверить каждый на соответствие определенным условиям. Если условия для очередного символа не выполнены, цикл прекращается:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">blnMatch = True </div><div class="code_line">For j - 1 То 5</div><div class="code_line">&nbsp;intCh = Asc(Mid$(strTest , j , 1)) </div><div class="code_line">&nbsp;Select Case j</div><div class="code_line">&nbsp;Case 1, 3, 4, 5</div><div class="code_line">&nbsp;&nbsp; If (IsCharAlpha(intCh) = 0) Then</div><div class="code_line">&nbsp;&nbsp; &nbsp;blnMatch = False</div><div class="code_line">&nbsp;&nbsp; End If </div><div class="code_line">&nbsp;Case 2</div><div class="code_line">&nbsp;&nbsp; If (IsCharAlpha(intCh) = 0) Then</div><div class="code_line">&nbsp;&nbsp; &nbsp;blnMatch = False </div><div class="code_line">&nbsp;&nbsp; End If </div><div class="code_line">&nbsp;End Select </div><div class="code_line">&nbsp;If Not blnMatch Then Exit For </div><div class="code_line">Next j</div></ol></div></div></div></div><br>
Приведенный выше код можно заменить строкой:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">blnMatch = strTest Like &quot;[A-Z]#[A-Z][A-Z][A-Z]&quot;</div></ol></div></div></div></div><br>
Здесь &quot;[A-Z]&quot; соответствует любому символу из диапазона от А до Z (для всех языков с латинским алфавитом), а &quot;#&quot; — любой цифре (0-9). И хотя возможности оператора Like ограниченны, иногда он может оказаться весьма полезным.<br>
<br>
<strong class='tag-b'>Пользуйтесь &#036;-функциями</strong><br>
<br>
Функция Left возвращает значение типа Variant, а функция Left&#036; — String. Если вы помещаете возвращаемое значение в переменную типа Variant, то имеет смысл использовать функцию Left. Однако чаще строки присваиваются строковым переменным, и в этом случае вызов Left заставит VBA выполнить дополнительное преобразование типов.<br>
<br>
<strong class='tag-b'>По возможности используйте целочисленное деление</strong><br>
<br>
В VBA имеются два оператора деления: обычный «/», для операций с плавающей точкой, и целочисленный - «&#092;». Для выполнения деления плавающей точкой VBA должен преобразовать оба операнда к этому типу данных. Поэтому, если дробная часть частного вам не нужна, можно сэкономить время, воспользовавшись оператором целочисленного деления.<br>
</span><br>
<br>
<span class='tag-size' data-value='8' style='font-size:8pt;'><span class="tag-color tag-color-named" data-value="gray" style="color: gray">Использованы материалы: &quot;From Access 2002 Desktop Developer&#39;s Handbook&quot;<br>
Litwin, Getz, and Gunderloy. (Sybex, 2001)</span></span>]]></description>
        <author>Old Bat</author>
        <category>Оптимизация VBA-кода</category>
      </item>
	
      </channel>
      </rss>
	