<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; VBScript: Отправка уведомлений на e-mail или SMS]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=6856&amp;type=atom" />
	<updated>2019-06-03T19:59:19Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=6856</id>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=134612#p134612" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>alexii пишет:</cite><blockquote><p><strong>DD</strong>, можно.</p></blockquote></div><p>Ну тогда я спокоен)).</p>]]></content>
			<author>
				<name><![CDATA[DD]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25263</uri>
			</author>
			<updated>2019-06-03T19:59:19Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=134612#p134612</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=134611#p134611" />
			<content type="html"><![CDATA[<p>Это да, но там баг был в том, что если запускать w32tm 64 бит нужно просто обрамлять список серверов кавычками (как это и написано в справке), а если w32tm 32 бит, то список серверов нужно обрамлять тройными кавычками.</p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-06-03T19:45:50Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=134611#p134611</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=134610#p134610" />
			<content type="html"><![CDATA[<p><strong>Malcev</strong>, я всегда стараюсь обрамлять имена/пути кавычками, наподобие:<br /></p><div class="codebox"><pre><code>If .Run(&quot;&quot;&quot;w32tm.exe&quot;&quot; /resync /rediscover&quot;, 0, True) &lt;&gt; 0 Then Exit Function</code></pre></div><p>и т.п.</p>]]></content>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2019-06-03T19:24:11Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=134610#p134610</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=134608#p134608" />
			<content type="html"><![CDATA[<p>Помню, обнаружили баг с w32tm: с 32-битной w32tm кавычки обрамляющие список серверов нужно утраивать.<br /><a href="http://forum.script-coding.com/viewtopic.php?id=12755">http://forum.script-coding.com/viewtopic.php?id=12755</a></p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-06-03T12:42:28Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=134608#p134608</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=134606#p134606" />
			<content type="html"><![CDATA[<p><strong>DD</strong>, можно.</p>]]></content>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2019-06-03T05:24:05Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=134606#p134606</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=134605#p134605" />
			<content type="html"><![CDATA[<p>Во втором коде была функция синхронизации времени. Можно ли ее отдельно запускать?<br /></p><div class="codebox"><pre><code>
	&#039;синхронизация времени с временем интернета
	Private Function TimeSinc()
		Set wshShell = CreateObject(&quot;WScript.Shell&quot;)
		With wshShell
			If .Run(&quot;w32tm /config /syncfromflags:manual /manualpeerlist:&quot; &amp; Chr(34) &amp; _
					&quot;ntp-servers.net time.windows.com time.nist.gov, time-nw.nist.gov, time-a.nist.gov, time-a.nist.gov&quot; &amp; Chr(34) _
					,0,True) &lt;&gt; 0 Then Exit Function
			If .Run(&quot;w32tm /config /update&quot;,0,True) &lt;&gt; 0 Then Exit Function
			
			If .Run(&quot;w32Tm /resync /rediscover&quot;,0,True) &lt;&gt; 0 Then Exit Function
		End With
		Set wshShell = Nothing
		TimeSinc = True	
	End Function
	</code></pre></div>]]></content>
			<author>
				<name><![CDATA[DD]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25263</uri>
			</author>
			<updated>2019-06-02T20:00:46Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=134605#p134605</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57716#p57716" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>BeS Yara пишет:</cite><blockquote><p>Полагаю что тут главное сделать скелет позволяющий посылать AT-команды модему и получать от него ответ. Дальше останется просто разобраться с AT-командами конкретного модема.</p></blockquote></div><p>Как-же я заблуждался <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.</p><p>Продолжаем разговор. Хочу представить мою текущую наработку - класс для формирования PDU для отправки в модем. </p><p>Свойства:<br /><strong>DebugMsg</strong>[def: False] - True включает вывод сообщений при работе(wscript.echo).<br /><strong>DeliveryReport</strong>[def: False] - СМС с уведомлением о доставке(если True)<br /><strong>IsFlashSMS</strong>[def: False] - Flash СМС(если True). на моей нокии просто по приходу СМС она сразу открывалась в штатном интерфейсе(блокировка экрана при этом остаётся).<br /><strong>RCPT</strong> - телефонный номер адресата в международном формате(&quot;+79998887766&quot;, можно и &quot;79998887766&quot;)<br /><strong>MessageText</strong> - текст СМС<br /><strong>SMSC</strong>[def: &quot;00&quot;] - номер СМС-центра. Возможные значения:<br />	1. телефонный номер в международном формате(&quot;+79037011111&quot;, для BeeLine MSK).<br />	2. &quot;00&quot; - брать номер из телефона/SIM-карты(работает не всегда).<br />	3. &quot;&quot; - действует аналогично &quot;00&quot;(на некоторых модемах может работать когда не работает &quot;00&quot;).<br /><strong>PartCount</strong> - свойство возвращает INTEGER, кол-во частей СМС сообщения. Доступно после задания MessageText. Только для чтения.<br /><strong>TP_VP</strong>[def: &quot;00&quot;] - строка содержит байт TP-Validity-Period(&quot;время жизни СМСЭ&quot; - время, по истечении которого сообщение в памяти SMSC уничтожается, если SMSC не получил уведомление о доставке сообщения получателем.). В данный момент прописаны значения:<br />	&quot;0B&quot; - Один час…<br />	&quot;1D&quot; - Три часа…<br />	&quot;47&quot; - Шесть часов…<br />	&quot;8F&quot; - Двенадцать часов…<br />	&quot;A7&quot; - Один день…<br />	&quot;C4&quot; - Одна неделя…<br />	&quot;FF&quot; - Максимальный срок хранения…<br />Значения для TP-VP взяты из ранее упомянутых мануалов. Нашел ещё одну <a href="http://electronix.ru/forum/index.php?act=attach&amp;type=post&amp;id=52572">инструкцию</a>(содержит массу информации сверх уже упомянутых статей), в ней описан алгоритм расчёта этого поля:<br /></p><div class="codebox"><pre><code>Формат VP определяется полем VPF (Validity Period Format). 
===========================================================================
|Значение VPF 	| Формат VP 						| Длина поля VP в байтах 	|
===========================================================================
|	00b 	| поле VP отсутствует 					|	0		|
|	01b 	| резерв в Siemens, расширенный формат для SonyEricsson 	|	-		|
|	10b 	| поле VP использует относительный формат 			|	1		|
|	11b 	| поле VP использует абсолютный формат 			|	7		|
===========================================================================
При задании относительного формата VP кодируется одним байтом в соответствии со следующей таблицей:

Значение VP, десятичное =&gt; Как считать VP
0 .. 143 =&gt; (VP + 1) * 5 минут = максимально можно задать 12 часов с шагом 5 минут
144 .. 167 =&gt; 12 часов + (VP – 143)*30 минут = максимально можно задать 24 часа
168 .. 196 =&gt; (VP – 166) * 1 день = максимально можно задать 30 дней 
197 .. 255 =&gt; (VP – 192) * 1 неделю = максимально можно задать 63 недели</code></pre></div><p><span style="color: grey">Как не хватает если уж не тега для таблиц, так хотябы чего-то вроде тега pre - для вывода моноширинным шрифтом с сохранением форматирования...Так и не смог табличку эту выровнять по человечески <img src="//forum.script-coding.com/img/smilies/sad.png" width="15" height="15" />.</span></p><p>Описанный алгоритм не реализовывал. <br />Да и в класс добавил это поле доступным для указания только потому оно было описано - реально не тестировал, и не слишком представляю практическую пользу для темы топика.<br />Если честно, есть сомнения в работоспособности поля, т.к.&nbsp; согласно цитируемому алгоритму</p><p>Метод только один:<br /><strong>SMS</strong> - возвращает двухмерный массив. Первая колонка - длина сообщения(для команды &quot;AT+CMGS=&quot;), вторая - PDU строка для скармливания модему.</p><p>Код класса:<br /></p><div class="codebox"><pre><code>
Class PDU_Encode
&#039; &quot;PDU-режим придумали разработчики - извращенцы. Придумали они его для того, чтобы поиметь мозги тех, кто будет с ним работать.&quot;
&#039; (c) StarXXX
  Private MaxLen7bit, MaxLen8bit, MaxLen16bit
  Private PDUType   &#039; Тип сообщения. Поле флагов. В некоторых источниках упоминается как SMS-SUBMIT-PDU
                    &#039; для исходящего СМС достаточно первых двух бит равно &quot;01&quot;
  Private TPMR      &#039; TP-Message-Reference - используется для длинных СМС
  Private TPPID     &#039; TP-Protocol ID
  Private TPDCS     &#039; TP-Data-Coding-Scheme – Схема кодирования данных. Указывает, в каком формате представлено сообщение.
  Private TPVP      &#039; TP-Validity-Period — время действия сообщения
  Private Recipient &#039; номер получателя
  Private SMS_Centr &#039; номер СМС-центра
  Private MsgText   &#039; текст СМС(тот что видится на экране телефона)
  Private SMSLen    &#039; длина TPDU(без SCA) - указывается в AT+CMGS=LEN
  Private FlashSMS  &#039; будем формировать всплывающую СМС(aka Flash)
  Private DelivRep   &#039; DeliveryReport
  Private IsUDH     &#039; требуется байт UDH(обычно для длинных СМС)
  Private IsTPVP    &#039; требуется ли байт TP-VP
  Private SMSPartCount  &#039; число частей длинной СМС
  Private SMSPartArr    &#039; массив содержащий части СМС
  Private IsCyr         &#039; маркер использования в СМС киррилицы
  Private LongPartUSCLim  &#039;USC-2, (140bit – 6byte под UDH) с 8-битным указателем, для сообщения остаётся 134 байта или 67 символов
  Private LongPart7bLim   &#039;7-бит, (140bit – 7byte под UDH) с 17-битным указателем, для сообщения остаётся 1133 байта или 152 символов
  Private IED_index       &#039;указатель каскадных сообщений
  Private Dbg             &#039; включение дополнительных сообщений по ходу работы скрипта

  Private Sub Class_Initialize
    MaxLen7bit = 160  &#039;за счёт упаковки 7-bit кодировки в 8-bit строку
    MaxLen8bit = 140  &#039;только если передавать не пользуясь PDU - одиночные английские СМС
                      &#039;теоретически, если PDU позволяет использовать 8-bit кодировку, можно и по 140 символов резать,
                      &#039;но смысла уже нет - с упаковкой разобрался.
    MaxLen16bit = 70  &#039;передача в юникоде, соотв. 140 байт делим пополам - остаётся только 70 символов
    PDUType = &quot;01&quot;  &#039; Исходящее сообщение
    TPMR = &quot;00&quot;     &#039; Короткое СМС, байт нулевой
    TPPID = &quot;00&quot;    &#039; TP-Protocol ID, описание пока не извесно
    TPDCS = &quot;08&quot;    &#039; 08h: кодировка UCS2 (тот же Unicode), 70 знаков, 2 байта на символ
    TPVP = &quot;00&quot;     &#039; TP-Validity-Period — время действия сообщения (если сообщение не будет получено абонентом в течение
                    &#039; этого времени, SMS-центр его удалит).
                    &#039; Если PDUType = &quot;01&quot;|&quot;21&quot;|&quot;41&quot;|&quot;61&quot;, то это поле в TPDU опускается
    Recipient = &quot;&quot;
    SMS_Centr = &quot;&quot;
    MsgText = &quot;&quot;
    SMSLen = 0
    FlashSMS  = False
    DelivRep  = False
    IsUDH     = False
    SMSPartCount = 0
    Redim SMSPartArr(1, 0)
    IsCyr = False
    LongPartUSCLim = 67
    LongPart7bLim = 152
    IED_index = &quot;&quot;  &#039;тут хранится &quot;Номер-ссылка&quot; - случайное число. одинаковое для всех частей одного длинного СМС
    Dbg = False
  End Sub

  &#039;############################################################################
  &#039;###  Class Properties                                                   ####
  &#039;############################################################################
  Public Property Let DebugMsg(param) &#039; тип СМС(всплывающая или обычная)
    If Not VarType(param)= 11 Then
      Err.Raise 60601, &quot;PDU&quot;, &quot;Incorrect Data Type. Need Boolean!&quot;
      Exit Property
    End If
    If param Then
        Dbg = True
      Else
        Dbg = False
    End If
  End Property
  Public Property Get DebugMsg()
    DebugMsg = Dbg
  End Property
  &#039;############################################################################
  Public Property Let IsFlashSMS(param) &#039; тип СМС(всплывающая или обычная)
    If Not VarType(param)= 11 Then
      Err.Raise 60602, &quot;PDU&quot;, &quot;Incorrect Data Type. Need Boolean!&quot;
      Exit Property
    End If
    If param Then
        FlashSMS = True
      Else
        FlashSMS = False
    End If
  End Property
  Public Property Get IsFlashSMS()
    IsFlashSMS = FlashSMS
  End Property
  &#039;############################################################################
  Public Property Let TP_VP(param) &#039; Время жизни СМС
    Select Case param &#039;известные допустимые значения параметра
      Case &quot;0B&quot; &#039; Один час…
        IsTPVP = True
      Case &quot;1D&quot; &#039; Три часа…
        IsTPVP = True
      Case &quot;47&quot; &#039; Шесть часов…
        IsTPVP = True
      Case &quot;8F&quot; &#039; Двенадцать часов…
        IsTPVP = True
      Case &quot;A7&quot; &#039; Один день…
        IsTPVP = True
      Case &quot;C4&quot; &#039; Одна неделя…
        IsTPVP = True
      Case &quot;FF&quot; &#039; Максимальный срок хранения…
        IsTPVP = True
      Case Else
        Err.Raise 60603, &quot;PDU&quot;, &quot;Incorrect PDU Type value.&quot;
        Exit Property
    End Select
    TPVP = param
  End Property
  Public Property Get TP_VP()
    TP_VP = TPVP
  End Property
  &#039;############################################################################
  Public Property Let RCPT(param) &#039; номер получателя в международном формате
    Dim SString
    SString = Trim(param)
    Dim f_regEx, f_Match, f_Matches, Shablon
    Set f_regEx = New RegExp
    f_regEx.Ignorecase = True
    f_regEx.Global = True
    f_regEx.Multiline = True
    f_regEx.Pattern = &quot;\+[\d]{11,}&quot;
    If f_regEx.Test(SString) Then
        Set f_Matches = f_regEx.Execute(SString)
          Recipient =  Replace(f_Matches(0).Value,&quot;+&quot;,&quot;&quot;)
        Else
          f_regEx.Pattern = &quot;[\d]{11,}&quot;
          If f_regEx.Test(SString) Then
              Set f_Matches = f_regEx.Execute(SString)
              Recipient =  f_Matches(0).Value
            Else
              Err.Raise 60604, &quot;PDU&quot;, &quot;Incorrect RCPT number.&quot;
              Exit Property
          End If
    End If
  End Property
  Public Property Get RCPT()
    RCPT = Recipient
  End Property
  &#039;############################################################################
  Public Property Let SMSC(param) &#039; номер СМС-центра в международном формате
    Dim SString
    SString = Trim(param) &#039; не указываем номер SMSC при формировании PDU
    If SString = &quot;&quot; Then
      SMS_Centr = SString
      Exit Property
    End If
    If SString = &quot;00&quot; Then  &#039; заменяем номер SMSC на &quot;00&quot; при формировании PDU
                            &#039;(номер СМС-центра должен подхватываться модемом с симки)
      SMS_Centr = SString
      Exit Property
    End If
    Dim f_regEx, f_Match, f_Matches, Shablon
    Set f_regEx = New RegExp
    f_regEx.Ignorecase = True
    f_regEx.Global = True
    f_regEx.Multiline = True
    f_regEx.Pattern = &quot;\+[\d]{11,}&quot;
    If f_regEx.Test(SString) Then
        Set f_Matches = f_regEx.Execute(SString)
          SMS_Centr =  Replace(f_Matches(0).Value,&quot;+&quot;,&quot;&quot;)
        Else
          f_regEx.Pattern = &quot;[\d]{11,}&quot;
          If f_regEx.Test(SString) Then
              Set f_Matches = f_regEx.Execute(SString)
              SMS_Centr =  f_Matches(0).Value
            Else
              Err.Raise 60605, &quot;PDU&quot;, &quot;Incorrect SMS-Centr number.&quot;
              Exit Property
          End If
    End If
  End Property
  Public Property Get SMSC()
    SMSC = SMS_Centr
  End Property
  &#039;############################################################################
  Public Property Let MessageText(param) &#039; текст СМС-ки
    MsgText = Trim(param) &#039; нефиг пробелы просто так слать :)
    If len(MsgText) = 0 Then
      Err.Raise 60606, &quot;PDU&quot;, &quot;Message text is empty!&quot;
      Exit Property
    End If
    Dim i &#039;, IsCyr
    For i = 1 To len(MsgText) &#039; ищем символы из верхнего диапазона кодов ASCII
      If Asc(Mid(MsgText, i, 1)) &gt; 127 Then IsCyr = True : Exit For
    Next
    If IsCyr And len(MsgText) &gt; MaxLen16bit Then &#039;USC-2
        If len(MsgText) \ LongPartUSCLim = len(MsgText) / LongPartUSCLim Then
            SMSPartCount = len(MsgText) \ LongPartUSCLim
          Else
            SMSPartCount = len(MsgText) \ LongPartUSCLim + 1
        End If
      Elseif Not IsCyr And len(MsgText) &gt; MaxLen7bit Then &#039;7-bit-&gt;8-bit
        If len(MsgText) \ LongPart7bLim = len(MsgText) / LongPart7bLim Then
            SMSPartCount = len(MsgText) \ LongPart7bLim
          Else
            SMSPartCount = len(MsgText) \ LongPart7bLim + 1
        End If
      Else
        SMSPartCount = 1
    End If
  End Property
  Public Property Get MessageText()
    MessageText = MsgText
  End Property
  &#039;############################################################################
  Public Property Let DeliveryReport(param) &#039; нужен ли отчёт о доставке?
    If VarType(param) = 11 Then
        DelivRep = param
      Else
        Err.Raise 60607, &quot;PDU&quot;, &quot;Incorrect Data Type. Need Boolean!&quot;
        Exit Property
    End If
  End Property
  Public Property Get DeliveryReport()
    DeliveryReport = DelivRep
  End Property
  &#039;############################################################################
  Public Property Let PartCount(param) &#039; считаем кол-во частей СМС
    &#039;Процедура создана для того чтобы в дереве процедур PSPad-а отображалось св-во PartCount :)
  End Property
  Public Property Get PartCount() &#039; считаем кол-во частей СМС
    PartCount = SMSPartCount
  End Property
  &#039;############################################################################
  &#039;###  Class Procedures                                                   ####
  &#039;############################################################################
  Private Function  TP_DA(num)  &#039; вычисление поля TP_DA (адресат)
    Dim NumLen, NumType
    NumType = &quot;91&quot;  &#039;международный формат
    If len(num)=0 Then
      Err.Raise 60605, &quot;PDU&quot;, &quot;Incorrect RCPT number!&quot;
      Exit Function
    End If
    &#039;длина номера(цифр без символа F) в хексе
    NumLen = Hex(len(num))
    If len(NumLen) = 1 Then NumLen = &quot;0&quot; &amp; NumLen
    If len(num)\2 = len(num)/2 Then
      TP_DA = num
      Else &#039; Нечётное число символов
      TP_DA = num &amp; &quot;F&quot;
    End If
    Dim i, str
    &#039;переворачиваем всё
    For i = 2 To len(TP_DA) step 2
      str = str &amp; Mid(TP_DA, i, 1) &amp; Mid(TP_DA, i-1, 1)
    Next
    TP_DA = NumLen &amp; NumType &amp; str
  End Function
  &#039;############################################################################
  Private Function SCA() &#039; вычисление поля SCA (SMS-центр)
    If SMS_Centr = &quot;&quot; Then
        SCA = &quot;00&quot;
      Else
        Dim SString, NumLen, NumType
        NumType = &quot;91&quot;  &#039;международный формат
        If len(SMS_Centr)\2 = len(SMS_Centr)/2 Then
          SCA = SMS_Centr
          Else &#039; Нечётное число символов
          SCA = SMS_Centr &amp; &quot;F&quot;
        End If
        Dim i, str
        &#039;переворачиваем всё
        For i = 2 To len(SCA) step 2
          str = str &amp; Mid(SCA, i, 1) &amp; Mid(SCA, i-1, 1)
        Next
        &#039;добавляем к номеру SMS-центра тип номера
        SCA = NumType &amp; str
        &#039;число бит получившейся строки, в хексе
        NumLen = Hex(len(SCA)/2)
        If len(NumLen) = 1 Then NumLen = &quot;0&quot; &amp; NumLen
        SCA = NumLen &amp; SCA
    End If
  End Function
  &#039;############################################################################
  Private Sub Str2USC2Hex() &#039;кодирование сообщения
    Dim i, str, j, Code
    For i = 0 To SMSPartCount - 1
      str = SMSPartArr(1, i)
      SMSPartArr(1, i) = &quot;&quot;
      For j = 1 To len(str)
        Code  = Hex(AscW(Mid(str, j, 1)))
        &#039;leading zero:
        If len(Code) &lt; 4 Then Code = String(4 - len(Code), &quot;0&quot;) &amp; Code
&#039;        If len(Code) = 1 Then Code = &quot;000&quot; &amp; Code &#039;управляющие символы
&#039;        If len(Code) = 2 Then Code = &quot;00&quot; &amp; Code &#039;символы ASCII - первый бит 00
&#039;        If len(Code) = 3 Then Code = &quot;0&quot; &amp; Code &#039;кирилица начинается с 0400
        SMSPartArr(1, i) = SMSPartArr(1, i) &amp; Code
      Next
    Next
  End Sub
  &#039;############################################################################
  Public Function SMS() &#039;формируем текст СМС, параллельно считаем длину TP-DU
    Call TPDU() &#039;формируем TP-DU
    If Dbg Then wscript.echo &quot;SMSPartCount = &quot; &amp; SMSPartCount
    If Dbg Then wscript.echo &quot;SCA = &quot; &amp; SCA
    For i = 0 To SMSPartCount - 1
      If Dbg Then wscript.echo SMSPartArr(1, i)
      SMSPartArr(1, i) = SCA &amp; SMSPartArr(1, i)
    Next
    SMS = SMSPartArr
    MsgText = &quot;&quot;
  End Function
  &#039;############################################################################
  Private Sub TPDU() &#039; сформированная строка для передачи момеду(одиночная СМС)
  &#039; 1. определиться с наличием кирилицы -&gt; кодировка(TP_DSC)
  &#039; 2. если кодировка 7-bit, то TP-UDL равен кол-ву символов сообщения
  &#039;    если кодировка UCS2, то TP-UDL равен кол-ву байт сообщения
    Dim TPUDL &#039; длина текста сообщения
    Dim TPUD  &#039; закодированный в 8-байтную строку текст сообщения

    If IsCyr And SMSPartCount = 1 Then
      &#039;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
        If Dbg Then wscript.echo &quot;PDU UCS2, single&quot;
        &#039; задаём значение байта кодировки:
        If FlashSMS Then
            TPDCS = &quot;18&quot;
          Else
            TPDCS = &quot;08&quot;
        End If
        Redim SMSPartArr(1, SMSPartCount - 1)
        For i = 0 To SMSPartCount - 1
          SMSPartArr(1, i) = MsgText
          SMSPartArr(0, i) = 2 * len(SMSPartArr(1, i)) &#039; для USC2 длина считается в байтах!
          &#039; в HEX переведём в самом конце, после прибавления длины UDH
          &#039;&#039;If len(SMSPartArr(0, i)) = 1 Then SMSPartArr(0, i) = &quot;0&quot; &amp; SMSPartArr(0, i)
          If Dbg Then wscript.echo &quot;SMSPartArr(0, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(0, i) &amp; &quot;; SMSPartArr(1, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(1, i)
        Next
        Call Str2USC2Hex() &#039; выполняем кодирование текста
      &#039;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
      Elseif IsCyr And SMSPartCount &gt; 1 Then
      &#039;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
        If Dbg Then wscript.echo &quot;PDU UCS2, long&quot;
        &#039; задаём значение байта кодировки:
        If FlashSMS Then
            TPDCS = &quot;18&quot;
          Else
            TPDCS = &quot;08&quot;
        End If
        Redim SMSPartArr(1, SMSPartCount - 1)
        For i = 0 To SMSPartCount - 1
          If i &lt; SMSPartCount - 1 Then
              SMSPartArr(1, i) = Left(MsgText, LongPartUSCLim) &#039;(140 – 6 под UDH) с 8-битным указателем
              SMSPartArr(0, i) = 2 * len(SMSPartArr(1, i))
              &#039; в HEX переведём в самом конце, после прибавления длины UDH
              MsgText = Right(MsgText, len(MsgText) - LongPartUSCLim)
            Else
              SMSPartArr(1, i) = Left(MsgText, LongPartUSCLim)
              SMSPartArr(0, i) = 2 * len(SMSPartArr(1, i))
              &#039; в HEX переведём в самом конце, после прибавления длины UDH
          End If
          If Dbg Then wscript.echo &quot;SMSPartArr(0, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(0, i) &amp; &quot;; SMSPartArr(1, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(1, i)
        Next
        Call Str2USC2Hex()
        IsUDH = True
      &#039;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
      Elseif Not IsCyr And SMSPartCount = 1 Then
      &#039;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
        If Dbg Then wscript.echo &quot;7-bit-&gt;8-bit PDU, single&quot;
        &#039; задаём значение байта кодировки:
        If FlashSMS Then
            TPDCS = &quot;10&quot;
          Else
            TPDCS = &quot;00&quot;
        End If

        Redim SMSPartArr(1, SMSPartCount - 1)
        For i = 0 To SMSPartCount - 1
          SMSPartArr(1, i) = MsgText
          SMSPartArr(0, i) = len(SMSPartArr(1, i))
          &#039; в HEX переведём в самом конце, после прибавления длины UDH
          If Dbg Then wscript.echo &quot;SMSPartArr(0, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(0, i) &amp; &quot;; SMSPartArr(1, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(1, i)
        Next
&#039;        TPUDL = Hex(len(MsgText)) &#039;TP-User-Data-Length – длина сообщения(символов) в HEX.
&#039;        TPUD = Encode7bit(MsgText)  &#039;TP-User-Data – непосредственно текст SMS-сообщения
        Call Encode7bit() &#039; выполняем кодирование текста
      Elseif Not IsCyr And SMSPartCount &gt; 1 Then
&#039;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
        If Dbg Then wscript.echo &quot;7-bit-&gt;8-bit, long&quot;
        &#039; задаём значение байта кодировки:
        If FlashSMS Then
            TPDCS = &quot;10&quot;
          Else
            TPDCS = &quot;00&quot;
        End If
        &#039; 16-битный указатель, предел 152 символов на часть
        Redim SMSPartArr(1, SMSPartCount - 1)
        For i = 0 To SMSPartCount - 1
          If i &lt; SMSPartCount - 1 Then
              SMSPartArr(1, i) = Left(MsgText, LongPart7bLim)
              SMSPartArr(0, i) = len(SMSPartArr(1, i))
              &#039; в HEX переведём в самом конце, после прибавления длины UDH
              MsgText = Right(MsgText, len(MsgText) - LongPart7bLim)
            Else
              SMSPartArr(1, i) = Left(MsgText, LongPart7bLim)
              SMSPartArr(0, i) = len(SMSPartArr(1, i))
              &#039; в HEX переведём в самом конце, после прибавления длины UDH
          End If
          If Dbg Then wscript.echo &quot;SMSPartArr(0, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(0, i) &amp; &quot;; SMSPartArr(1, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(1, i)
        Next
        IsUDH = True
        Call Encode7bit() &#039; выполняем кодирование текста
&#039;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
    End If
    Dim TPDA
    TPDA = TP_DA(Recipient) &#039;TP-Destination-Address – Номер телефона получателя сообщения
    &#039; Определимся с типом сообщения
    Call PDU_Type()
    Dim TPDU
    If Dbg Then wscript.echo &quot;PDU-Type = &quot; &amp; PDUType
    For i = 0 To SMSPartCount - 1
      If Dbg Then wscript.echo &quot;Long SMS; Part [&quot; &amp; i + 1 &amp; &quot;]/[&quot; &amp; SMSPartCount &amp; &quot;]&quot;
      &#039; TP-UDL: прибавляем к длине закодированного сообщения длину заголовка UDH
      If IsCyr Then &#039; длина текста указывается в байтах для USC-2 и в символах для 7-bit!!!
          &#039; Для USC2 длина равна числу символов *2. Удвоение длины делается в момент формирования массива SMSPartArr!!!
          If IsUDH Then &#039; для длинных СМС учитываем блок UDH
              TPUDL = GetByte(SMSPartArr(0, i) + 6, 1) &#039; для USC-2 длина вдвое больше кол-ва символов(2 байта на символ).
                                                          &#039; указатель однобайтний и заголовок UDH имеет длину 6 byte
            Else
              TPUDL = GetByte(SMSPartArr(0, i), 1)
          End If
        Else
          If IsUDH Then &#039; для длинных СМС учитываем блок UDH
              TPUDL = GetByte(SMSPartArr(0, i) +8, 1)  &#039; при +7 теряется последний символ каждой СМС...
                                                        &#039; при +8 длинные СМС идут нормально, но хотелось бы понять причину...
            Else
              TPUDL = GetByte(SMSPartArr(0, i), 1)
          End If
      End If
      TPUD = SMSPartArr(1, i)
      &#039; по некоторым данным, для длинного СМС должно иметь разное значение среди остальных кусков
      If SMSPartCount &gt; 1 Then
        TPMR = GetByte(i + 1, 1)
      End If
      Dim UDHtmp
      Select Case PDUType
        Case &quot;01&quot;, &quot;21&quot; &#039;исх. сообщ.; \A + отчёт о доставке
          If Dbg Then wscript.echo &quot;01 TPDU без SCA =&gt;&quot; &amp; PDUType &amp; &quot; &quot; &amp; TPMR &amp; &quot; &quot; &amp; TPDA &amp; &quot; &quot; &amp; TPPID &amp; &quot; &quot; &amp; TPDCS &amp; &quot; &quot; &amp; TPUDL &amp; &quot; &quot; &amp; TPUD
          TPDU = PDUType &amp; TPMR &amp; TPDA &amp; TPPID &amp; TPDCS &amp; TPUDL &amp; TPUD
          If Dbg Then wscript.echo &quot;TPDU без SCA =&gt;&quot; &amp; TPDU
        Case &quot;41&quot;, &quot;61&quot; &#039;исх. сообщ. + UDH; \A + отчёт о доставке !!!!!!!!!!!!!!!!!!!
          UDHtmp = UDH(i+1)
          If Dbg Then wscript.echo &quot;41 TPDU без SCA =&gt;&quot; &amp; PDUType &amp; &quot; &quot; &amp; TPMR &amp; &quot; &quot; &amp; TPDA &amp; &quot; &quot; &amp; TPPID &amp; &quot; &quot; &amp; TPDCS &amp; &quot; &quot; &amp; TPUDL &amp; &quot; &quot; &amp; UDHtmp &amp; &quot; &quot; &amp; TPUD
          TPDU = PDUType &amp; TPMR &amp; TPDA &amp; TPPID &amp; TPDCS &amp; TPUDL &amp; UDHtmp &amp; TPUD
          SMSPartArr(1, i) = TPDU
          If Dbg Then wscript.echo &quot;TPDU без SCA =&gt;&quot; &amp; TPDU
        Case &quot;11&quot;, &quot;31&quot; &#039;исх. сообщ. + TP-VP; \A + отчёт о доставке
          If Dbg Then wscript.echo &quot;11 TPDU без SCA =&gt;&quot; &amp; PDUType &amp; &quot; &quot; &amp; TPMR &amp; &quot; &quot; &amp; TPDA &amp; &quot; &quot; &amp; TPPID &amp; &quot; &quot; &amp; TPDCS &amp; &quot; &quot; &amp; TPVP &amp; &quot; &quot; &amp; TPUDL &amp; &quot; &quot; &amp; TPUD
          TPDU = PDUType &amp; TPMR &amp; TPDA &amp; TPPID &amp; TPDCS &amp; TPVP &amp; TPUDL &amp; TPUD
          If Dbg Then wscript.echo &quot;51 TPDU без SCA =&gt;&quot; &amp; TPDU
        Case &quot;51&quot;, &quot;71&quot; &#039;исх. сообщ. + UDH + TP-VP; \A + отчёт о доставке
          UDHtmp = UDH(i+1)
          If Dbg Then wscript.echo &quot;11 TPDU без SCA =&gt;&quot; &amp; PDUType &amp; &quot; &quot; &amp; TPMR &amp; &quot; &quot; &amp; TPDA &amp; &quot; &quot; &amp; TPPID &amp; &quot; &quot; &amp; TPDCS &amp; &quot; &quot; &amp; TPVP &amp; &quot; &quot; &amp; TPUDL &amp; &quot; &quot; &amp; UDHtmp &amp; &quot; &quot; &amp; TPUD
          TPDU = PDUType &amp; TPMR &amp; TPDA &amp; TPPID &amp; TPDCS &amp; TPVP &amp; TPUDL &amp; UDHtmp &amp; TPUD
          If Dbg Then wscript.echo &quot;51 TPDU без SCA =&gt;&quot; &amp; TPDU
      End Select
      SMSPartArr(1, i) = TPDU
      SMSPartArr(0, i) = len(SMSPartArr(1, i))/2
      If Dbg Then wscript.echo &quot;SMSPartArr(0, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(0, i) &amp; &quot;; SMSPartArr(1, &quot; &amp; i &amp; &quot;) = &quot; &amp; SMSPartArr(1, i)
      If Dbg Then wscript.echo &quot;IED_index = &quot; &amp; IED_index
    Next
  End Sub
  &#039;############################################################################
  Private Function UDH(k)
    Dim UDHL, IEI, IEDL, IED
    &#039; IEI
    &#039; вариантов использования много, для СМС есть два значение:
    &#039; «00h» – Связанное короткое сообщение. 8-битный указатель…
    &#039; «08h» – Связанное короткое сообщение. 16-битный указатель…
    Dim b1_b2, b3, b4
    &#039; b1 &amp; b2 - при IEI=&quot;08&quot;, при &quot;00&quot; остаётся только b1
    &#039; составляют указатель каскадных сообщений (случайное число от 0 до 255|65535). Для всех частей длинной СМС должны быть одинаковы
    &#039; b3 - число сегментов сообщения
    &#039; b4 - порядковый номер сообщения
    b3 = GetByte(SMSPartCount, 1)
    If Dbg Then wscript.echo &quot;b3 = &quot; &amp; b3
    b4 = GetByte(k, 1)
    If Dbg Then wscript.echo &quot;b4 = &quot; &amp; b4
    If Not IsCyr Then   &#039;ASCII
        UDHL = &quot;06&quot; &#039;User Data Header Length
        IEI = &quot;08&quot;  &#039;Information Element Identifier
        IEDL = &quot;04&quot; &#039;Information Element Data Length
        &#039;Т.к. указатель одинаков для всех частей, то генерим при первом вызове процедуры
        If IED_index = &quot;&quot; Then IED_index = Rand2b
      Else  &#039;USC-2
        UDHL = &quot;05&quot; &#039;User Data Header Length
        IEI = &quot;00&quot;  &#039;Information Element Identifier
        IEDL = &quot;03&quot; &#039;Information Element Data Length
        If IED_index = &quot;&quot; Then IED_index = Rand1b
    End If
    b1_b2 = IED_index
    If Dbg Then wscript.echo &quot;b1_b2 = &quot; &amp; b1_b2
    &#039;UDH = UDHL + IEI + IEDL + IED
    IED = b1_b2 &amp; b3 &amp; b4
    UDH = UDHL &amp; IEI &amp; IEDL &amp; IED
    If Dbg Then wscript.echo &quot;UDH = &quot; &amp; UDH
  End Function
  &#039;############################################################################
  Private Function GetByte(str, size) &#039; получение байта или двух...
    GetByte = Hex(str)
    If len(GetByte) &lt; 4 Then
      If size = 1 Then GetByte = String(2 - len(GetByte), &quot;0&quot;) &amp; GetByte
      If size = 2 Then GetByte = String(4 - len(GetByte), &quot;0&quot;) &amp; GetByte
    End If
  End Function
  &#039;############################################################################
  Private Function Rand1b() &#039; рандомное однобайтовое число
    Randomize
    Do
      Rand1b = (1000 * Rnd) \ 1
    Loop While Rand1b &gt; 255
    Rand1b = Hex(Rand1b)
    If len(Rand1b) = 1 Then Rand1b = &quot;0&quot; &amp; Rand1b
  End Function
  &#039;############################################################################
  Private Function Rand2b() &#039; рандомное двубайтовое число
    Randomize
    Do
      Rand2b = (1000 * Rnd) \ 1
    Loop While Rand2b &gt; 65535
    Rand2b = Hex(Rand2b)
    If len(Rand2b) &lt; 4 Then Rand2b = String(4-len(Rand2b), &quot;0&quot;) &amp; Rand2b
  End Function
  &#039;############################################################################
  Private Sub PDU_Type() &#039; определяемся с типом СМС(PDU-Type)
    If Not IsTPVP And Not DelivRep And Not IsUDH Then
        PDUType = &quot;01&quot;
      Elseif IsTPVP And Not DelivRep And Not IsUDH Then
        PDUType = &quot;11&quot;
      Elseif Not IsTPVP And DelivRep And Not IsUDH Then
        PDUType = &quot;21&quot;
      Elseif  IsTPVP And  DelivRep And Not IsUDH Then
        PDUType = &quot;31&quot;
      Elseif Not IsTPVP And Not DelivRep And IsUDH Then
        PDUType = &quot;41&quot;
      Elseif IsTPVP And Not DelivRep And IsUDH Then
        PDUType = &quot;51&quot;
      Elseif Not IsTPVP And DelivRep And IsUDH Then
        PDUType = &quot;61&quot;
      Elseif IsTPVP And DelivRep And IsUDH Then
        PDUType = &quot;71&quot;
    End If
  End Sub
  &#039;############################################################################
  &#039;###  Упаковка 7-bit текста в 8-bit строку                                ###
  &#039;############################################################################
  Private Sub Encode7bit()
    Dim arr7b() &#039;массив для 7bit кодов
    Dim arr8b() &#039;массив для кодирования в 8bit
    Dim j, str
    For j = 0 To SMSPartCount - 1
      str = SMSPartArr(1, j)
      &#039; &quot;набиваем&quot; 7bit массив:
      Dim i : i = 0
      Dim bCode : bCode = &quot;&quot;
      Do While len(str) &lt;&gt; 0
        bCode = dec2bin(Asc(Left(str, 1))) &#039; ASCII код символа в двоичном виде
        Redim Preserve arr7b(i) &#039; перезадаём размер массива(кроме первого шага - увеличение размерности на 1)
        If len(bCode) &lt; 7 Then &#039; дополняем код нулями до 7 бит
          bCode = String(7 - len(bCode), &quot;0&quot;) &amp; bCode
        End If
        If i = 150 Then
          bCode = bCode
        End If
        arr7b(i) = bCode
        str = Right(str, len(str) - 1) &#039;откусываем от строки один символ слева
        i = i + 1
      Loop
      &#039; В результате, имеем на выходе массив, каждый элемент которого - код символа в двоичном виде(7 бит).
      Redim arr8b(UBound(arr7b)) &#039;задаём размер как для 7-бит массива
      &#039; &quot;сжимаем&quot; 7-битную строку в 8-битную:
      Dim DlinaKuska
      &#039; проходим по таблице, на каждом 8-ом элементе(i=7...15... ) &quot;пропускаем ход&quot;
      &#039; в конце &quot;очищаем&quot; массив от пустых значений
      &#039; внутри &quot;круга&quot; &quot;откусывается&quot; у следущего элемента массива:  i + 1 - (i\8) * 8
      &#039; внутри &quot;круга&quot; &quot;остаётся&quot; у следущего элемента массива:    7 - (i + 1 - (i\8) * 8)
      &#039; &quot;круг&quot; - период за который при упаковке &quot;исчезает&quot; 1 байт - на пальцах сложно объяснить, см. &quot;SendSMS_PDU_Part_1.pdf&quot;
      For i = 0 To UBound(arr7b)
        If i &lt; UBound(arr7b) Then &#039; пока не дошли до последнего элемента массива...
            If (i+1)\8 = (i+1)/8 Then &#039;каждый 8-ой элемент(i=7, i=15 ets) нулевой
                arr8b(i) = &quot;&quot;
              Else
                DlinaKuska = i + 1 - (i\8) * 8 &#039;длина = (индекс элемента + 1) за вычетом полных &quot;кругов&quot;
                &#039; формируем текущий байт приписывая к текущему 7-битному часть следующего 7-битного
                arr8b(i) = Right(arr7b(i + 1), DlinaKuska) &amp; arr7b(i)
                &#039; укорачиваем следующий 7-битный элемент на величину &quot;позаимствованных&quot; данных
                arr7b(i+1) = Left(arr7b(i+1), 7 - DlinaKuska)
            End If
          Else
            &#039; если элемент последний, то просто дорисовываем недостающие нули(единообразия ради)
            &#039; конечно если элемент не пустой...
            If len(arr7b(i)) &lt;&gt; 0 Then arr8b(i) = String(8 - len(arr7b(i)), &quot;0&quot;) &amp; arr7b(i)
        End If
      Next
      &#039;удаляем пустые элементы(можно бы и без этого, но так красивее :)
      Call CompactArray(arr8b)
      &#039;формируем строку сообщения в Hex:
      Dim str8b_h, substr
      str8b_h = &quot;&quot;
      For i = 0 To UBound(arr8b)
        substr = Hex(bin2dec(arr8b(i)))
        If len(substr) = 1 Then substr = &quot;0&quot; &amp; substr
        str8b_h = str8b_h &amp; substr
      Next
      SMSPartArr(1, j) = str8b_h
    Next
  End Sub
  &#039;############################################################################
  Private Sub CompactArray(Byref arr) &#039; очистка динамического одномерного массива от пустых элементов
    Dim i
    &#039; помечаем пустые элементы:
    For i = 0 To UBound(arr)
      If arr(i) = &quot;&quot; Then arr(i) = &quot;del&quot;
    Next
    Dim arrNew
    &#039; формируем массив без удаляемых ячеек:
    arrNew = Filter(arr, &quot;del&quot;, False)
    &#039; переразмериваем переданный в процедуру массив(без сохранения данных)
    Redim arr(UBound(arrNew))
    &#039; заполняем его отфильтованными элементами:
    For i = 0 To UBound(arrNew)
      arr(i) = arrNew(i)
    Next
  End Sub
  &#039;############################################################################
  Private Function bin2dec(num) &#039; кодирование из двоичной в десятичную систему
    Dim i : i = 0
    bin2dec = 0
    Do While len(num) &lt;&gt; 0
      bin2dec = bin2dec + CInt(Right(num, 1))*2^i
      num = left(num, len(num) - 1) &#039;откусываем один символ справа
      i = i + 1
    Loop
  End Function
  &#039;############################################################################
  Private Function dec2bin(num) &#039; кодирование из десятичную в двоичной систему
    Dim i : i = 0
    dec2bin = &quot;&quot;
    Dim tmp, ost
    Do While num &lt;&gt; 0
      dec2bin = CStr(num - 2 * (num \ 2)) &amp; dec2bin
      num = num\2
    Loop
  End Function
End Class</code></pre></div><p>Пример использования:<br /></p><div class="codebox"><pre><code>
Option Explicit

Dim MSComm
Set MSComm = WScript.CreateObject(&quot;MSCommLib.MSComm&quot;, &quot;Modem_&quot;)
With MSComm
  .CommPort = 8
  .Handshaking = 0 &#039;ComNone Нет подтверждения связи (Значение по умолчанию)
  .Settings = &quot;9600,N,8,1&quot; &#039;Установка скорости в бодах,контроль по четности,число битов данных,число стоповых битов
  .InputLen = 0 &#039;Используем весь буфер(при запросе возвращается ВЕСЬ текущий буфер)
  .Rthreshold = 1
End With

Dim ComState    &#039;статус выполнения команды
Dim wPortResp   &#039;ожидаемый ответ модема
Dim PortResp    &#039;ответ модема
Dim LastCommand &#039;последняя отданая команда(для отладки)
PortResp = vbNullString
ComState = vbNullString
&#039; Открываем порт:
If Not MSComm.PortOpen Then MSComm.PortOpen = True

&#039; Готовим объект
Dim PDU
Set PDU = New PDU_Encode

&#039; Посылаем команды в порт:
&#039; пинганули...
SendATCommand &quot;AT&quot;, &quot;OK&quot;
&#039; узнаем номер СМС-центра
SendATCommand &quot;AT+CSCA?&quot;, &quot;OK&quot;
&#039; задаём параметры для кодирования в PDU
With PDU
  .RCPT = &quot;+79998887766&quot;
  .SMSC = GetSMSC(PortResp)
  .MessageText = &quot;Да не беги ты! Видишь, сзади две,&quot; &amp; vbCrLf &amp; _
                  &quot;И обе из порядочного дома.&quot; &amp; vbCrLf &amp; _
                  &quot;Одна из них с соседями в родстве,&quot; &amp; vbCrLf &amp; _
                  &quot;И потому мы шапочно знакомы.&quot; &amp; vbCrLf &amp; _
                  &quot;Раскланяемся с ними, подойдем&quot; &amp; vbCrLf &amp; _
                  &quot;И совершим прогулку, вчетвером.&quot;
End With

&#039; Задаём формат СМС сообщения:
SendATCommand &quot;AT+CMGF=0&quot;, &quot;OK&quot;

Dim arr, i
arr = PDU.SMS &#039; получаем части для скармливания модему
For i = 0 To PDU.PartCount - 1
  &#039; Начинаем отправку сообщения:
  SendATCommand &quot;AT+CMGS=&quot; &amp; arr(0,i), &quot;&gt;&quot;
  &#039; передаём текст сообщения и отправляем:
  SendATCommand arr(1,i) &amp; Chr(26), &quot;OK&quot;
Next

&#039; Закрываем порт:
MSComm.PortOpen = False
Wscript.Quit 0


Sub SendATCommand(command, WaitFor) &#039;отправка команд в модем
  ComState = vbNullString
  If InStr(WaitFor, &quot;&gt;&quot;) &lt;&gt; 0 Then
      wPortResp = WaitFor
    Else
      wPortResp = WaitFor &amp; Chr(13) &amp; Chr(10)
  End If
  LastCommand = command
    MSComm.Output = command &amp; Chr(13) &amp; Chr(10)
  Dim i : i = 0
  Dim iLim : iLim = 20
  Do While ComState = vbNullString
    wscript.echo i &amp; &quot;...&quot;
    wscript.sleep 1000
    i = i + 1
    If i &gt; iLim Then
      wscript.echo &quot;время вышло&quot;
      wscript.quit(0)
    End If
  Loop
End Sub

Sub Modem_OnComm() &#039;отслеживание событий на COM-порте
  Select Case MSComm.CommEvent
    Case 2 &#039;comEvReceive
      PortResp = MSComm.Input
      If InStr(PortResp, LastCommand) &lt;&gt; 0 Then wscript.echo LastCommand

      If InStr(PortResp, wPortResp) &lt;&gt; 0 Then
        &#039;wscript.echo PortResp
        wscript.echo &quot;Команда &quot; &amp; LastCommand &amp; &quot; выполнена успешно.&quot;
        ComState = &quot;OK&quot;
      End If
      If InStr(PortResp, &quot;ERROR&quot;) &lt;&gt; 0 Then
        wscript.echo &quot;Команда &quot; &amp; LastCommand &amp; &quot; вызвала ошибку: &quot; &amp; vbCrLf &amp; PortResp
        ComState = &quot;ERROR&quot;
      End If
  End Select
End Sub

Function GetSMSC(resp) &#039;получение номера СМС-центра
  Dim SString, NumLen, NumType
  SString = Trim(resp)
  Dim f_regEx, f_Match, f_Matches, Shablon
  Set f_regEx = New RegExp
  f_regEx.Ignorecase = True
  f_regEx.Global = True
  f_regEx.Multiline = True
  f_regEx.Pattern = &quot;\+[\d]+&quot;
  If f_regEx.Test(SString) Then
      Set f_Matches = f_regEx.Execute(SString)
        GetSMSC = f_Matches(0).Value
      Else
        Exit Function
  End If
End Function</code></pre></div>]]></content>
			<author>
				<name><![CDATA[BeS Yara]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25643</uri>
			</author>
			<updated>2012-03-11T11:20:14Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57716#p57716</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57568#p57568" />
			<content type="html"><![CDATA[<p>Тогда продолжаем тут <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.<br />Выдалось свободное время, позанимался велосипедом. Результат - заготовка для отправки сообщения в PDU(т.е. можно и на русском). Пока только одиночное(проверку на длину не делал - всё-таки экспериментальный образец <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />), но как пример работы должно сойти:</p><div class="codebox"><pre><code>&#039; VB Script Document
Option Explicit
Dim RCPT, Text
RCPT = &quot;+79997776655&quot; &#039; кому шлём
Text = &quot;Привет МИР!!!&quot; &amp; vbCrLf &amp; &quot;Меня зовут Вася.&quot;

Dim TPDU, PDUType, TPMR, TPDA, TPPID, TPDCS, TPVP, TPUDL, TPUD, MsgLen
PDUType = &quot;01&quot;  &#039;Тип сообщения. Поле флагов. В некоторых источниках упоминается как SMS-SUBMIT-PDU
                &#039; для исходящего СМС достаточно первых двух байт равно &quot;01&quot;
TPMR = &quot;00&quot; &#039; TP-Message-Reference, используется в длинных СМС
TPDA = fTPDA(RCPT) &#039;TP-Destination-Address – Номер телефона получателя сообщения
TPPID = &quot;00&quot; &#039;TP-Protocol ID
TPDCS = &quot;08&quot; &#039;TP-Data-Coding-Scheme – Схема кодирования данных. Указывает, в каком формате представлено сообщение.
              &#039;00h: кодировка 7-бит (160 знаков, но не кириллическая, только латинские символы)
              &#039;08h: кодировка UCS2 (тот же Unicode), 70 знаков, 2 байта на символ
              &#039;10h: Flash-сообщение, кодировка 7-бит
              &#039;18h: Flash-сообщение, кодировка UCS2
TPVP = &quot;00&quot; &#039;TP-Validity-Period — время действия сообщения (если сообщение не будет получено абонентом в течение этого
            &#039;времени, SMS-центр его удалит)
            &#039;если PDUType = &quot;01&quot;, то это поле в TPDU опускается

TPUDL = Hex(2 * len(Text)) &#039;TP-User-Data-Length – длина сообщения(в байтах - по два байта на символ) в HEX.
If len(TPUDL) = 1 Then TPUDL = &quot;0&quot; &amp; TPUDL &#039;leading zero

TPUD = Str2USC2Hex(Text)&#039;TP-User-Data – непосредственно текст SMS-сообщения, закодированный согласно полю TP-DCS

If PDUType = &quot;01&quot; Then
    wscript.echo PDUType &amp; &quot; &quot; &amp; TPMR &amp; &quot; &quot; &amp; TPDA &amp; &quot; &quot; &amp; TPPID &amp; &quot; &quot; &amp; TPDCS &amp; &quot; &quot; &amp; TPUDL &amp; &quot; &quot; &amp; TPUD
    TPDU = PDUType &amp; TPMR &amp; TPDA &amp; TPPID &amp; TPDCS &amp; TPUDL &amp; TPUD
  Elseif PDUType = &quot;11&quot; Then &#039;как 01, но &quot;Включает&quot; поле TP-VP
    wscript.echo PDUType &amp; &quot; &quot; &amp; TPMR &amp; &quot; &quot; &amp; TPDA &amp; &quot; &quot; &amp; TPPID &amp; &quot; &quot; &amp; TPDCS &amp; &quot; &quot; &amp; TPVP &amp; &quot; &quot; &amp; TPUDL &amp; &quot; &quot; &amp; TPUD
    TPDU = PDUType &amp; TPMR &amp; TPDA &amp; TPPID &amp; TPDCS &amp; TPVP &amp; TPUDL &amp; TPUD
End If

MsgLen = len(TPDU)/2 &#039;длина сообщения без указания СМС-центра

&#039;TPDU = &quot;00&quot; &amp; TPDU  &#039;добавляем СМС-центр

&#039; Начинаем работать с модемом
Dim MSComm
Set MSComm = WScript.CreateObject(&quot;MSCommLib.MSComm&quot;, &quot;Modem_&quot;)
With MSComm
  .CommPort = 8
  .Handshaking = 0 &#039;ComNone Нет подтверждения связи (Значение по умолчанию)
  .Settings = &quot;9600,N,8,1&quot; &#039;Установка скорости в бодах,контроль по четности,число битов данных,число стоповых битов
  .InputLen = 0 &#039;Используем весь буфер(при запросе возвращается ВЕСЬ текущий буфер)
  .Rthreshold = 1
End With

Dim ComState    &#039;статус выполнения команды
Dim wPortResp   &#039;ожидаемый ответ модема
Dim PortResp    &#039;ответ модема
Dim LastCommand &#039;последняя отданая команда(для отладки)
PortResp = vbNullString
ComState = vbNullString
&#039; Открываем порт:
If Not MSComm.PortOpen Then
  MSComm.PortOpen = True
End If
Wscript.echo &quot;MSComm.PortOpen: &quot; &amp; cstr(MSComm.PortOpen)
wscript.echo &quot;Rthreshold = &quot; &amp; MSComm.Rthreshold

&#039; Посылаем команду в порт:
SendATCommand &quot;AT&quot;, &quot;OK&quot;
SendATCommand &quot;AT+CSCA?&quot;, &quot;OK&quot;
&#039;wscript.echo &quot;[&quot; &amp; PortResp &amp; &quot;]&quot;
&#039;wscript.echo &quot;номер СМС-центра: &quot; &amp; GetSMSC(PortResp)
TPDU = fSCA(GetSMSC(PortResp)) &amp; TPDU  &#039;добавляем СМС-центр
&#039; Задаём формат СМС сообщения:
SendATCommand &quot;AT+CMGF=0&quot;, &quot;OK&quot;
&#039; Начинаем отправку сообщения:
SendATCommand &quot;AT+CMGS=&quot; &amp; MsgLen, &quot;&gt;&quot;
&#039; передаём текст сообщения и отправляем:
SendATCommand TPDU &amp; Chr(26), &quot;OK&quot;
&#039; Закрываем порт:
MSComm.PortOpen = False
Wscript.Quit 0

&#039;Возможные ошибки:
&#039;+CMS ERROR: 330
&#039;Примечание: неизвестен сервис-центр
&#039;+CMS ERROR: 304
&#039;Примечание: неверный параметр PDU

Sub SendATCommand(command, WaitFor) &#039;отправка команд в модем
  ComState = vbNullString
  If InStr(WaitFor, &quot;&gt;&quot;) &lt;&gt; 0 Then
      wPortResp = WaitFor
    Else
      wPortResp = WaitFor &amp; Chr(13) &amp; Chr(10)
  End If
  LastCommand = command
    MSComm.Output = command &amp; Chr(13) &amp; Chr(10)
  Dim i : i = 0
  Dim iLim : iLim = 10
  Do While ComState = vbNullString
    wscript.echo i &amp; &quot;...&quot;
    wscript.sleep 1000
    i = i + 1
    If i &gt; iLim Then Exit Do
  Loop
End Sub

Sub Modem_OnComm() &#039;отслеживание событий на COM-порте
  Select Case MSComm.CommEvent
    Case 2 &#039;comEvReceive
      PortResp = MSComm.Input
      If InStr(PortResp, LastCommand) &lt;&gt; 0 Then wscript.echo LastCommand

      If InStr(PortResp, wPortResp) &lt;&gt; 0 Then
        &#039;wscript.echo PortResp
        wscript.echo &quot;Команда &quot; &amp; LastCommand &amp; &quot; выполнена успешно.&quot;
        ComState = &quot;OK&quot;
      End If
      If InStr(PortResp, &quot;ERROR&quot;) &lt;&gt; 0 Then
        wscript.echo &quot;Команда &quot; &amp; LastCommand &amp; &quot; вызвала ошибку: &quot; &amp; vbCrLf &amp; PortResp
        ComState = &quot;ERROR&quot;
      End If
  End Select
End Sub

Function Str2USC2Hex(str) &#039;кодирование сообщения
  Str2USC2Hex = &quot;&quot;
  Dim i, Code
  For i = 1 To len(str)
    Code  = Hex(AscW(Mid(str, i, 1)))
    &#039;leading zero:
    If len(Code) = 1 Then Code = &quot;000&quot; &amp; Code &#039;управляющие символы
    If len(Code) = 2 Then Code = &quot;00&quot; &amp; Code &#039;символы ASCII - первый байт 00
    If len(Code) = 3 Then Code = &quot;0&quot; &amp; Code &#039;кирилица, начинается с 0400
    Str2USC2Hex = Str2USC2Hex &amp; Code
  Next
End Function

&#039;Номер получателя: убираем все, кроме цифр, дописываем в конец «F», если количество цифр в номере нечетное,
&#039;а затем переставляем местами цифры в каждой паре. Перед номером идут длина и тип номера
Function fTPDA(num) &#039;Номер телефона, переворачиваем всё
  Dim SString, NumLen, NumType
  SString = Trim(num)
  NumType = &quot;91&quot;  &#039;международный формат
  Dim f_regEx, f_Match, f_Matches, Shablon
  Set f_regEx = New RegExp
  f_regEx.Ignorecase = True
  f_regEx.Global = True
  f_regEx.Pattern = &quot;[\d]+&quot;
  If f_regEx.Test(SString) Then
      Set f_Matches = f_regEx.Execute(SString)
        fTPDA = f_Matches(0).Value
      Else
        Exit Function
  End If
  &#039;длина номера(цифр без символа F) в хексе
  NumLen = Hex(len(fTPDA))
  If len(NumLen) = 1 Then NumLen = &quot;0&quot; &amp; NumLen
  If len(fTPDA)\2 = len(fTPDA)/2 Then
    fTPDA = fTPDA
    Else &#039; Нечётное число символов
    fTPDA = fTPDA &amp; &quot;F&quot;
  End If
  Dim i, str
  &#039;переворачиваем всё
  For i = 2 To len(fTPDA) step 2
    str = str &amp; Mid(fTPDA, i, 1) &amp; Mid(fTPDA, i-1, 1)
  Next
  fTPDA = NumLen &amp; NumType &amp; str
End Function

&#039; два отличия от fTPDA:
&#039; длина берётся номера вместе с типом номера(а не цифр).
&#039; длина равна числу байт номера, а не цифр.
Function fSCA(num) &#039;Номер телефона, переворачиваем всё
  Dim SString, NumLen, NumType
  SString = Trim(num)
  NumType = &quot;91&quot;  &#039;международный формат
  Dim f_regEx, f_Match, f_Matches, Shablon
  Set f_regEx = New RegExp
  f_regEx.Ignorecase = True
  f_regEx.Global = True
  f_regEx.Pattern = &quot;[\d]+&quot;
  If f_regEx.Test(SString) Then
      Set f_Matches = f_regEx.Execute(SString)
        fSCA = f_Matches(0).Value
      Else
        Exit Function
  End If
  If len(fSCA)\2 = len(fSCA)/2 Then
    fSCA = fSCA
    Else &#039; Нечётное число символов
    fSCA = fSCA &amp; &quot;F&quot;
  End If
  Dim i, str
  &#039;переворачиваем всё
  For i = 2 To len(fSCA) step 2
    str = str &amp; Mid(fSCA, i, 1) &amp; Mid(fSCA, i-1, 1)
  Next
  &#039;добавляем к номеру SMS-центра тип номера
  fSCA = NumType &amp; str
  &#039;число байт получившейся строки, в хексе
  NumLen = Hex(len(fSCA)/2)
  If len(NumLen) = 1 Then NumLen = &quot;0&quot; &amp; NumLen
  fSCA = NumLen &amp; fSCA
End Function

Function GetSMSC(resp) &#039;получение номера СМС-центра
  Dim SString, NumLen, NumType
  SString = Trim(resp)
  Dim f_regEx, f_Match, f_Matches, Shablon
  Set f_regEx = New RegExp
  f_regEx.Ignorecase = True
  f_regEx.Global = True
  f_regEx.Multiline = True
  f_regEx.Pattern = &quot;\+[\d]+&quot;
  If f_regEx.Test(SString) Then
      Set f_Matches = f_regEx.Execute(SString)
        GetSMSC = f_Matches(0).Value
      Else
        Exit Function
  End If
End Function</code></pre></div><p>Длинные СМС, полагаю, не сильно сложнее. Но решил идти по шагам, да и когда продолжу не знаю, а так может ещё кто-то присоединится.</p><p>Чтобы не усложнять описание в посте: во-первых, порядок действий по кодированию PDU максимально повторяет инструкцию, во-вторых, постарался по максимуму прокоментировать в коде.<br />Первоначально работало и с 00 вместо номера СМС-центра, потом модем глюкануло и перестал отправлять в таком виде. Поэтому скрипт сначала запрашивает номер СМС-центра у модема, и использует его.</p><p>Также немного поправил работу с модемом - выяснилось что появление в приёмном буффере символа &quot;&gt;&quot; не сопровождается CR+LF. Т.к. ошибки по таймауту не генерировал, влияло только на скорость.</p><p>Наткнулся в одном из форумов на &quot;усовершенствованную&quot; инструкцию(на основе приведённых статей с hardisoft.ru с добавлениями и исправлениями). Прямые ссылки:<br /><a href="http://www.cyberforum.ru/attachment.php?attachmentid=72352&amp;d=1302697914">Send_SMS_PDU_Part_1.pdf</a><br /><a href="http://www.cyberforum.ru/attachment.php?attachmentid=73315&amp;d=1303213545">Send_SMS_PDU_Part_2.pdf</a><br />Если напрямую не будет качается, вот <a href="http://www.cyberforum.ru/csharp-beginners/thread269949.html">тема</a> - в конце первой и начале второй страниц приложены файлы.</p><p>Первое что бросилось в глаза - больше информации по TP-ID. По крайней мере стало ясно отсутствие одного байта в примере, а то голову ломал где я ошибся <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.<br />З.Ы. если кому-то захочется воспользоваться прослушкой COM-порта, то рекомендую &quot;COM Port Toolkit&quot;. Прога достаточно функциональная, и недорогая(мой ключик уже пришел <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />). Для сравнения можно попробовать бесплатный Portmon от Sysinternals. Я попробовал, не понравилось.</p>]]></content>
			<author>
				<name><![CDATA[BeS Yara]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25643</uri>
			</author>
			<updated>2012-03-06T13:40:52Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57568#p57568</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57498#p57498" />
			<content type="html"><![CDATA[<p>Не возражаю.</p>]]></content>
			<author>
				<name><![CDATA[dab00]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27085</uri>
			</author>
			<updated>2012-03-05T08:42:32Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57498#p57498</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57495#p57495" />
			<content type="html"><![CDATA[<p><strong>BeS Yara</strong>, не вижу смысл создавать новую тему, так как обсуждение идет в отношении отправки уведомлений по SMS. Проще заголовок темы чуток подкорректировать, если <strong>dab00</strong> не возражает.</p>]]></content>
			<author>
				<name><![CDATA[JSmаn]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24434</uri>
			</author>
			<updated>2012-03-05T08:04:34Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57495#p57495</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57480#p57480" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>JSman пишет:</cite><blockquote><p>Что касается инициализации ZTE, то я делал так:</p></blockquote></div><p>Мне кажется достаточно оставить:<br /></p><div class="codebox"><pre><code>        this.Send(&quot;ATZ&quot;);
        this.Send(&quot;AT+CPBS=\&quot;SM\&quot;&quot;);
        this.Send(&quot;AT+CPMS=\&quot;SM\&quot;,\&quot;SM\&quot;,\&quot;\&quot;&quot;);
        this.Send(&#039;AT+CSCS=&quot;UCS2&quot;&#039;);</code></pre></div><p>Если модем используется только скриптом, то и в ATZ я не вижу необходимости.</p><p>Или есть какой-то практический смысл сбросить конфигурацию, погасить модем и включить его назад? Если судить по линуксоидам(им чаще всего приходится общаться с модемами посредством AT-команд), то этот процесс может занять от 5 до 15 секунд.<br />З.Ы. раз тема работы с GSM представляет интерес, может стоит выделить её в отдельную тему, вроде &quot;WSH: работа с модемом посредством AT-команд&quot;? Будет проще собрать воедино все идеи и наработки <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.</p>]]></content>
			<author>
				<name><![CDATA[BeS Yara]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25643</uri>
			</author>
			<updated>2012-03-05T05:03:48Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57480#p57480</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57475#p57475" />
			<content type="html"><![CDATA[<p>Искал как раз эту информацию. Большое спасибо.</p>]]></content>
			<author>
				<name><![CDATA[Valerman]]></name>
			</author>
			<updated>2012-03-05T01:52:51Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57475#p57475</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57471#p57471" />
			<content type="html"><![CDATA[<p>Что касается инициализации ZTE, то я делал так:<br /></p><div class="codebox"><pre><code>        this.Send(&quot;ATZ&quot;);
        this.Send(&quot;AT+ZSTOPT&quot;);
        this.Send(&quot;AT+ZOPRT=6&quot;);
        this.Send(&quot;AT+ZOPRT=5&quot;);
        this.Send(&quot;AT+ZSTART&quot;);
        this.Send(&quot;AT+CPBS=\&quot;SM\&quot;&quot;);
        
        this.Send(&quot;AT+CPMS=\&quot;SM\&quot;,\&quot;SM\&quot;,\&quot;\&quot;&quot;);
        this.Send(&#039;AT+CSCS=&quot;UCS2&quot;&#039;);</code></pre></div><p>Проверка доступности услуг<br /></p><div class="codebox"><pre><code>_this.Send(&quot;AT+ZDON?&quot;);_this.Send(&quot;AT+ZPAS?&quot;);_this.Send(&quot;AT+CSQ&quot;);</code></pre></div><p>Чтение кодировки при получении сведений о балансе (HexUCS2ToUnicode):<br /></p><div class="codebox"><pre><code>var Encoding = 
{
    Convert : function (Text,SourceCharset,DestCharset)
    {
        var Stream = new ActiveXObject(&quot;ADODB.Stream&quot;);
        Stream.Type = 2;
        Stream.Mode = 3;
        Stream.Open();
        Stream.Charset = SourceCharset;
        Stream.WriteText (Text);
        Stream.Position = 0;
        Stream.Charset = DestCharset;
        return Stream.ReadText;
    }, 

    HexToBin : function (Data)
    {
        var oXML, oNode;
        oXML = new ActiveXObject(&quot;Msxml2.DOMDocument.6.0&quot;);
        oNode = oXML.createElement(&quot;data&quot;);
        oNode.dataType = &quot;bin.hex&quot;;
        oNode.text = Data;
        return oNode.nodeTypedValue;
    },

    HexUCS2ToUnicode : function (s)
    {
        return Encoding.Convert(Encoding.HexToBin(s), &quot;UTF-16BE&quot;, &quot;Unicode&quot;)
    }
}</code></pre></div><p>Как допишу расшифровку входящих, то полный код выложу.</p>]]></content>
			<author>
				<name><![CDATA[JSmаn]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24434</uri>
			</author>
			<updated>2012-03-04T18:25:33Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57471#p57471</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57446#p57446" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>dab00 пишет:</cite><blockquote><p>Зацепило уважаемого BeS Yara <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />. Навыки работы с модемом на уровне AT-команд - интересно, спасибо.<br />Что касается &quot;резервного канала&quot; в виде USB-модема - по-моему изобретение велосипеда тут ни к чему - воткнул этот модем в сеть, добавил в свойства TCP/IP сетевого интерфейса дополнительный шлюз и забыл.</p></blockquote></div><p>Думаю <strong>Slav</strong> имел ввиду резервный канал связи именно как СМС-информер админа о проблемах. С целью информировать админа о ЧС СМС, как мне кажется, гораздо оперативнее чем GPRS с последующим использованием вэб-сервисов или отправкой почты. И уж конечно надёжнее чем рассчитывать на то что основной канал не лёг <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.<br />Тогда это отнюдь не велосипед. Хотя могу и ошибаться.</p><p>Ну а работать напрямую с модемом не так сложно как может показаться, по крайнеё мере для простейших случаев <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.<br />Допустим нам нужно информировать админа о проблемах с интернетом или об отключении электричества в офисе. Админ человек образованный - транслит прочитает, упрощённый английский тоже осилит. Да и лимита в 140 символов должно хватить(краткость сестра таланта). Поэтому главное препядствие(кодирование в PDU) отпадает и остаётся мелочь:</p><div class="codebox"><pre><code>&#039; VB Script Document
Option Explicit

Dim MSComm
Set MSComm = WScript.CreateObject(&quot;MSCommLib.MSComm&quot;, &quot;MSComm_&quot;)
With MSComm
  .CommPort = 8
  .Handshaking = 0 &#039;ComNone Нет подтверждения связи (Значение по умолчанию)
  .Settings = &quot;9600,N,8,1&quot; &#039;Установка скорости в бодах,контроль по четности,число битов данных,номер стопового бита
  .InputLen = 0 &#039;Используем весь буфер(при запросе возвращается ВЕСЬ текущий буфер)
End With

If Not MSComm.PortOpen Then MSComm.PortOpen = True
Wscript.echo &quot;MSComm.PortOpen: &quot; &amp; cstr(MSComm.PortOpen)
&#039; Посылаем команду в порт:
SendATCommand &quot;AT&quot;, &quot;OK&quot;
&#039; Задаём формат СМС сообщения:
SendATCommand &quot;AT+CMGF=1&quot;, &quot;OK&quot;
&#039; Начинаем отправку сообщения:
SendATCommand &quot;AT+CMGS=&quot;&quot;+76667778899&quot;&quot;,145&quot;, &quot;&gt;&quot;
&#039; передаём текст сообщения и отправляем:
SendATCommand &quot;Hello World!&quot; &amp; vbCrLf &amp; &quot;I&#039;m The Robot!&quot; &amp; Chr(26), &quot;OK&quot;

&#039; Закрываем порт:
MSComm.PortOpen = False

Sub SendATCommand(command, WaitFor)
  Dim i : i = 0
  Dim iLim : iLim = 5
  Dim Buff
  &#039; посылаем команду в порт:
  MSComm.Output = command &amp; vbCrLf
  &#039; Ожидаем ответ:
  Do While InStr(Buff, WaitFor) = 0
    Buff = Buff &amp; MSComm.Input
    i = i + 1
    wscript.echo i &amp; &quot;=&gt; &quot; &amp; Buff &amp; &quot; [InStr = &quot; &amp; InStr(Buff, &quot;OK&quot; &amp; vbCrLf) &amp; &quot;]&quot;
    If i &gt; iLim Then Exit Do
    wscript.sleep 1000
  Loop
End Sub</code></pre></div><p>или так:<br /></p><div class="codebox"><pre><code>&#039; VB Script Document
Option Explicit

Dim MSComm
Set MSComm = WScript.CreateObject(&quot;MSCommLib.MSComm&quot;, &quot;Modem_&quot;)
With MSComm
  .CommPort = 8
  .Handshaking = 0 &#039;ComNone Нет подтверждения связи (Значение по умолчанию)
  .Settings = &quot;9600,N,8,1&quot; &#039;Установка скорости в бодах,контроль по четности,число битов данных,число стоповых битов
  .InputLen = 0 &#039;Используем весь буфер(при запросе возвращается ВЕСЬ текущий буфер)
  .Rthreshold = 1
End With

Dim ComState    &#039;статус выполнения команды
Dim wPortResp   &#039;ожидаемый ответ модема
Dim PortResp    &#039;ответ модема
Dim LastCommand &#039;последняя отданая команда(для отладки)
PortResp = vbNullString
ComState = vbNullString
&#039; Открываем порт:
If Not MSComm.PortOpen Then MSComm.PortOpen = True

&#039; Посылаем команду в порт:
SendATCommand &quot;AT&quot;, &quot;OK&quot;
&#039; Задаём формат СМС сообщения:
SendATCommand &quot;AT+CMGF=1&quot;, &quot;OK&quot;
&#039; Начинаем отправку сообщения:
SendATCommand &quot;AT+CMGS=&quot;&quot;+76667778899&quot;&quot;,145&quot;, &quot;&gt;&quot;
&#039; передаём текст сообщения и отправляем:
SendATCommand &quot;Hello World!&quot; &amp; vbCrLf &amp; &quot;I&#039;m The Robot!&quot; &amp; Chr(26), &quot;OK&quot;

&#039; Закрываем порт:
MSComm.PortOpen = False
Wscript.Quit 0


Sub SendATCommand(command, WaitFor)
  ComState = vbNullString
  wPortResp = WaitFor
  LastCommand = command
  MSComm.Output = command &amp; Chr(13) &amp; Chr(10)
  Dim i : i = 0
  Dim iLim : iLim = 5
  Do While ComState = vbNullString
    wscript.echo i &amp; &quot;...&quot;
    wscript.sleep 1000
    i = i + 1
    If i &gt; iLim Then Exit Do
  Loop
End Sub

Sub Modem_OnComm()
  Select Case MSComm.CommEvent
    Case 2 &#039;comEvReceive
      PortResp = MSComm.Input
      If InStr(PortResp, LastCommand) &lt;&gt; 0 then wscript.echo LastCommand
      If InStr(PortResp, wPortResp &amp; vbCrLf) &lt;&gt; 0 then
        wscript.echo &quot;Команда &quot; &amp; LastCommand &amp; &quot; выполнена успешно.&quot;
        ComState = &quot;OK&quot;
      end if
      If InStr(PortResp, &quot;ERROR&quot;) &lt;&gt; 0 then wscript.echo &quot;Команда &quot; &amp; LastCommand &amp; &quot; вызвала ошибку: &quot; &amp; vbCrLf &amp; PortResp
  End Select
End Sub</code></pre></div><p>Скрипты сделаны практически на коленке - <a href="http://msdn.microsoft.com/en-us/library/aa259393(v=vs.60).aspx">MSDN:MSComm Control</a> + ранние изыскания по AT-командам + COM-сниффер. Собственно два скрипта - два упомянутых в MSDN метода работы с объектом(через посылку команд с последующим считыванием приёмного буфера и через отслеживание событий OnComm).</p><p>Конечно нужна двухсторонняя связь - админ может послать в СМС команду, которую скрипт выполнит. Тут уже будет несколько посложнее. Кодирование/декодирование в PDU - дополнительные сложности(хотя я бы не сказал что нерешаемые). Другой вопрос что весь этот функционал уже реализован в упомянутой мной утилите(имеющей более чем приемлимые ограничения при бесплатном использовании, за что разработчикам мегареспект) и времени делать велосипед мне жалко(хотя и интересно).<br />З.Ы. примеры проверены на билайновском &quot;свистке&quot;(ZTE-626). Правда он был уже инициализирован - с нуля может потребуется добавить пару команд до или после AT(AT, вообще-то не нужен особо - просто вместа &quot;пинга&quot;, удостовериться что всё ОК):<br /></p><div class="codebox"><pre><code>&#039; Для ZTE-626
SendATCommand &quot;AT+CPBS=&quot;&quot;SM&quot;&quot;&quot;, &quot;OK&quot;
SendATCommand &quot;AT+CPMS=&quot;&quot;SM&quot;&quot;,&quot;&quot;SM&quot;&quot;,&quot;&quot;&quot;&quot;&quot;, &quot;OK&quot;</code></pre></div><p>Хотя и без них отправляется, но если не выполнить эти команды, то модем будет слать в приёмный буфер &quot;+ZUSIMR:2&quot; каждые пару секунд. При некоторых условиях это может стать проблемой.</p>]]></content>
			<author>
				<name><![CDATA[BeS Yara]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25643</uri>
			</author>
			<updated>2012-03-04T12:40:37Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57446#p57446</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: Отправка уведомлений на e-mail или SMS]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=57392#p57392" />
			<content type="html"><![CDATA[<p>Зацепило уважаемого BeS Yara <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />. Навыки работы с модемом на уровне AT-команд - интересно, спасибо.<br />Что касается &quot;резервного канала&quot; в виде USB-модема - по-моему изобретение велосипеда тут ни к чему - воткнул этот модем в сеть, добавил в свойства TCP/IP сетевого интерфейса дополнительный шлюз и забыл.</p>]]></content>
			<author>
				<name><![CDATA[dab00]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27085</uri>
			</author>
			<updated>2012-03-02T05:43:59Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=57392#p57392</id>
		</entry>
</feed>
