Новости:

Название темы должно отражать суть задачи.
Темы типа "ПОМОГИТЕ!!!", "Срочно!" и т.п. будут удаляться без объяснения причин

Главное меню

Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.

Просмотр сообщений

Сообщения - Igorilla_777

#1
Проблема решена. Вот код бат-файла. Была добавлена последняя строка.
[spoiler]
@echo off
:: Имя соединения
set connection=Internet Contract
rasdial "%connection:"=%"
echo %ERRORLEVEL% > c:\ProgramData\ET_Balans\Errordial_log.txt
[/spoiler]

В результате создается файл Errordial_log.txt в указанном каталоге с кодом ошибки. Его я смогу вернуть в VBA.
Спасибо всем, участвовавшим в теме.
Тема закрыта.
#2
The_Prist! Я правда никого не хотел обидеть! Прочитав сначала Ваш ответ, я подумал, что речь шла о переменной VBA. Не
Теперь то я понял, что Вы говорили вначале. Ну, протупил, не сообразил сразу! Мне важно любое мнение людей, которые нашли время отвечать на мои вопросы! Я не часто обращаюсь на форумы за помощью, и Ваши советы мне очень помогают. Извините за оффтоп.
#3
Пфффф... %errorlevel% ...!  Это, похоже, выход из данной ситуации! Придется копать теперь в этом направлении. А где подробнее можно прочитать, КАК отловить ошибку при помощи %errorlevel% в командном файле? Я с синтаксисом и командами командных файлов знаком на уровне совсем начинающего. Интуитивно я понял смысл сказанного, а вот практическая реализация в голове пока не укладывается. 
AndreTM, спасибо за дельный совет!))) Не в обиду остальным участникам темы.
#4
Прошу помощи у тех, кому повезло научиться коннектиться по DialUP через код VBA.
Функция  RasGetEntryDialParams и RasDial возвращают ошибку, что не найдена запись телефонной книги. Грешу, что в структуре RASDIALPARAMS что-то не так. Может, размер структуры задаю не так. Помогите добиться работоспособности этого кода!

[spoiler]

Option Explicit

Const RAS_MaxEntryName = 256
Const RAS_MaxPhoneNumber = 128
Const RAS_MaxCallbackNumber = RAS_MaxPhoneNumber
Const RAS_MaxAreaCode = 10
Const RAS_MaxDeviceType = 16
Const RAS_MaxDeviceName = 128
Const RAS_MaxPadType = 32
Const RAS_MaxX25Address = 200
Const RAS_MaxFacilities = 200
Const RAS_MaxUserData = 200
Const UNLEN = 256
Const PWLEN = 256
Const DNLEN = 15
Private Type RASDIALPARAMS

dwSize As Long ' 1052
dwSubEntry As Long
dwIfIndex As Long
dwCallbackId As Long
szEntryName(RAS_MaxEntryName + 1) As Byte
szPhoneNumber(RAS_MaxPhoneNumber + 1) As Byte
szCallbackNumber(RAS_MaxCallbackNumber + 1) As Byte
szUserName(UNLEN + 1) As Byte
szPassword(PWLEN + 1) As Byte
szDomain(DNLEN + 1) As Byte

End Type

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, ByVal pSrc As String, ByVal ByteLen As Long)
Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" (Destination As Any, ByVal Length As Long)
Private Declare Function RasDial Lib "rasapi32.dll" Alias "RasDialA" (ByVal lprasdialextensions As Long, ByVal lpcstr As String, ByRef lprasdialparamsa As RASDIALPARAMS, ByVal dword As Long, lpvoid As Any, ByRef lphrasconn As Long) As Long
Private Declare Function RasGetEntryDialParams Lib "rasapi32.dll" Alias "RasGetEntryDialParamsA" (ByVal lpcstr As String, ByRef lprasdialparamsa As RASDIALPARAMS, ByRef lpbool As Long) As Long

Sub gogogo()
Form.Show

End Sub
Private Sub Dial_xx()



Dim FParams As RASDIALPARAMS
Dim FConnHandle  As Long
Dim lpbool As Long

Dim t As Long
Dim resp As Long

Dim Path As String

FParams.dwSize = 1052

ChangeBytes "Internet Contract", FParams.szEntryName ' загнали текст имени соединения в переменную szEntryName (в виде байтов)

'path = "c:\ProgramData\Microsoft\Network\Connections\Pbk\rasphone.pbk" ' путь к телефонной книге. Из нее соединения коннектятся отлично

             t = RasGetEntryDialParams(vbNullString, FParams, lpbool)

FConnHandle = 0

            resp = RasDial(ByVal 0, ByVal 0, FParams, 0, ByVal 0, FConnHandle)
End Sub

Private Function ChangeBytes(ByVal str As String, Bytes() As Byte) As Boolean
'Конвертор текстовой стоки из Юникода в читабельный байтовый массив. Его кушает RasAPI:))
'Returns True if it truncates str
Dim lenBs As Long 'length of the byte array
Dim lenStr As Long 'length of the string
lenBs = UBound(Bytes) - LBound(Bytes)
lenStr = LenB(StrConv(str, vbFromUnicode))
If lenBs > lenStr Then
CopyMemory Bytes(0), str, lenStr
ZeroMemory Bytes(lenStr), lenBs - lenStr
ElseIf lenBs = lenStr Then
CopyMemory Bytes(0), str, lenStr
Else
CopyMemory Bytes(0), str, lenBs
ChangeBytes = True
End If
End Function

[/spoiler]

Вопрос пытался решить здесь: http://www.excel-vba.ru/forum/index.php?topic=2586.0
Обошел эту проблему через запуск бат-файла из VBA : http://www.excel-vba.ru/forum/index.php?topic=2650.new#new

Текст батника такой (где-то на форумах нашел и модифицировал под себя):
[spoiler]

@echo off
:: Имя соединения
set connection=Internet Contract
rasdial "%connection:"=%"
pause

[/spoiler]
Интересует все же первый способ коннекта через VBA посредством фции RasDial как более гибкий и технологичный.
#5
Хороший вопрос! Статус подключения я могу определить. Вот, например, я не подключился. А как мне сообщить юзеру о том, что за ошибка подключения возникла?
Да, посмотри в окно cmd.exe! Там написано! Но это же не по нашему! Окно может запускаться скрытым и вообще как бы не нужнО, умей я установить коннект непосредственно через VBA... А так я пытаюсь сделать коннект через ж..., но сообщения об проблемах коннекта юзеру выдать не смогу. Печаль.
#6
Кстати,все было бы проще, если бы был ответ на мой ранее заданный вопрос:
http://www.excel-vba.ru/forum/index.php?topic=2586.0

Не пришлось бы изгаляться с bat-файлами... )))))
#7
По поводу кросспостинга- хотел привести сноску на форумы, где задал вопрос, но не сделал. Приношу извинения! И принимаю к сведению замечания...))

Суть вопроса вот в чем... Я запускаю бат- файл командой shell. Запускается выполнения кода бат-файла, и VBA возвращает мне код ошибки выполнения приложения-0 (все ОК, команда прошла успешно).
[spoiler]

Sub start_dial_bat()
' запускаем созданный батник
Dim TaskID As Double
Dim Programm As String

On Error Resume Next

Programm = Range("dial_bat_Path")
TaskID = Shell(Programm, vbNormalNoFocus)

If Err <> 0 Then
MsgBox "Error " & Err, vbCritical, "Ошибка!"
End If

End Sub

[/spoiler]
Однако при выполнении кода бат-файла выходит ошибка Windows, например, 623... В окне cmd.exe мне честно об этом сообщается. Собственно, это не ошибка выполнения кода VBA, верно? Я хотел бы знать, как ее отловить для обработки...  Собственно, мне нужна не ошибка кода VBA , а запускаемого приложения.

Изначально передо мной ставилась задача обеспечить Dialup соединение посредством функции RasDial из кода VBA. Конечно, в этом случае код ошибки выполнения этой функции я получал бы сразу в VBA и мог бы ее обработать. Но вот у меня никак не получается добиться от этой функции нормальной работы. Форумы ответа не дали по моей проблеме. Поэтому я решил использовать команду rasdial (через командную строку). Этот вариант работает отлично? но коды ошибок генерирует никак не в VBA ))) Я то их вижу в окне, но этого мало....
Может, зная ID (получаю в переменной TaskID) запущенного процесса, попытаться его обработать?
#8
Привет всем! Ребята, посоветуйте, как можно получить код ошибки Windows, которая может возникнуть при выполнении приложения?
К примеру, я стартую .bat- файл, который устанавливает интернет- соединение. Возможны случаи, когда система по какой-либо причине возвращает ошибку, о чем сообщает в окне cmd.exe. Как мне перехватить из VBA код этой ошибки для дальнейшей обработки?
#9
Доброго времени суток всем! Прошу дельного совета по возникшей проблеме.

Вводные данные по софту и оборудованию:
Система: Windows 7 Prof SP1
Модем: HUAWEI Mobile Connect - 3G Modem. Провайдер: Киевстар. Вид подключения:EDGE
EXCEL: Excel 2003 SP3

Описание проблемы.
Имеется соединение с сетью посредством 3G модема HUAWEI. Модем определен в системе как ряд виртуальных устройств- USB-накопителя и модема собственно. Оболочка управления модемом автоматически инсталлится в систему при первом подключении. В дальнейшем можно выбрать тип подключения (Contract,Prepaid, XL, 3G и тп) Работаю по умолчанию на Internet Contract. Все соединения отображаются также в окне подключений Windows. Работаю с модемом через его программную оболочку.

Модем имеет неприятное свойство дисконнектиться по непонятной причине случайным образом или показывать соединение с сетью, но пинг не проходит- модем типа "зависает")).

Моя программа должна принимать и отправлять данные в Интернет посредством этого ненадежного "свистка". Собственно, при таком коннекте о полной автоматизации речи идти не может. Я поставил задачу определить наличие связи с Интернетом (пингуя сервер), и, если связи нет, пересбросить модем и подключиться вновь по соединению, заданному по умолчанию.
В процессе поиска решений данной проблемы докопался до функций RasAPI. На сегодня я  программно могу проверить наличие доступных соединений, сделать дисконнект соединения. А вот с коннектом происходят непонятки. Не получается установить соединение.

Лог моих действий и возникающие при этом проблемы:

1. Делаю вручную дисконнект (имитация разрыва связи)- успешно;
2. Программно проверяю наличие доступных соединений (RasEnumEntries)- успешно;
3. Программно пытаюсь получить данные по выбранному соединению(RasGetEntryDialParams)- возвращаемый массив почему-то пуст. Нет ни UserName, ни  PhoneNumber...
4. Программно пытаюсь подконнектиться с параметрами соединения по умолчанию (RasDial) .
4.1. Первое подключение- возвращает код 0- успешное соединение и тут же выкидывает сообщение:"Run-time error:-2147417848 (80010108) Automation error. Вызванный объект был отключен от клиентов"
4.2. Повторные попытки коннекта по данному соединению возвращает код 756- "соединение уже используется".
При этом соединение физически не устанавливается. При попытке подключиться через оболочку 3G модема или стандартную Windows (в обеих случаях присутствует кнопка "Подключение"), модем выдает ошибку 756- "соединение уже выполнено".

До тех пор, пока открыто мое приложение  Excel, ситуация не меняется. Выбранное соединение занято чем-то и доступ к нему не происходит. После закрытия приложения Excel  (при этом система долго думает) сразу становится возможным установить связь штатными средствами.

Я проверял работу модуля  на XP, но ситуация та же. Компиляция кода VBA происходит без ошибок типов и тп. Люди добрые,  я уже всю плешь проел с этой проблемой! Возможно, 3G модем как-то влияет на типовое использование функций RasAPI. Я в тупике... Проверить работу модуля на другом модеме не имею возможности.

Для примера приведу код, который я использовал для проверки возможности программного подключения к сети:

[spoiler]
'Программа выводит UserForm с названиями доступных соединений.
'После выбора соединения в List1 и нажатия кнопки Command1
'должен произойти коннект по выбранному соединению.


Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, ByVal pSrc As String, ByVal ByteLen As Long)
Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" (Destination As Any, ByVal Length As Long)
' константы для структуры RASDIALPARAMS
Const RAS95_MaxEntryName = 256
Const RAS_MaxPhoneNumber = 128
Const RAS_MaxCallbackNumber = RAS_MaxPhoneNumber
Const UNLEN = 256
Const PWLEN = 256
Const DNLEN = 12

' описываем структуру RASDIALPARAMS (для функций RasGetEntryDialParams и RasDial). Структура содержит параметры выбранного соединения
Private Type RASDIALPARAMS
   dwSize As Long ' размер структуры (1052 байт)
   szEntryName(RAS95_MaxEntryName) As Byte ' Имя соединения
   szPhoneNumber(RAS_MaxPhoneNumber) As Byte ' Телефонный номер соединения
   szCallbackNumber(RAS_MaxCallbackNumber) As Byte
   szUserName(UNLEN) As Byte ' Имя пользователя
   szPassword(PWLEN) As Byte ' Пароль
   szDomain(DNLEN) As Byte ' Домен
End Type

' описываем структуру RASENTRYNAME95 (для функции RasEnumEntries)
Private Type RASENTRYNAME95
    dwSize As Long ' размер структуры (264 байт)
    szEntryName(RAS95_MaxEntryName) As Byte ' Имя соединения
End Type

Private Declare Function RasDial Lib "rasapi32.dll" Alias "RasDialA" (ByVal lprasdialextensions As Long, ByVal lpcstr As Long, ByRef lprasdialparamsa As RASDIALPARAMS, ByVal dword As Long, lpvoid As Any, ByRef lphrasconn As Long) As Long
Private Declare Function RasEnumEntries Lib "rasapi32.dll" Alias "RasEnumEntriesA" (ByVal reserved As String, ByVal lpszPhonebook As String, lprasentryname As Any, lpcb As Long, lpcEntries As Long) As Long
Private Declare Function RasGetEntryDialParams Lib "rasapi32.dll" Alias "RasGetEntryDialParamsA" (ByVal lpcstr As String, ByRef lprasdialparamsa As RASDIALPARAMS, ByRef lpbool As Long) As Long


Private Sub UserForm_Activate()
   
    Command1.Caption = "Dial"
    Dim s As Long, i As Long, ln As Long, a$
    ReDim rdp(255) As RASENTRYNAME95
   
    rdp(0).dwSize = 264
    s = 256 * rdp(0).dwSize ' задали размер структуры
    i = RasEnumEntries(vbNullString, vbNullString, rdp(0), s, ln) ' получили имена всех доступных соединений и сохранили их в массиве rdp
    ' функция вернет в переменной ln количество доступных соединений
    ' заполняем читабельными именами ListBox
    For i = 0 To ln - 1
        a$ = StrConv(rdp(i).szEntryName(), vbUnicode)
        List1.AddItem Left$(a$, InStr(a$, Chr$(0)) - 1)
    Next
    If List1.ListCount > 0 Then
        List1.ListIndex = 0
        List1_Click
    End If

End Sub

Private Sub List1_Click()
    ' выбор соединения для коннекта
    Dim rdp As RASDIALPARAMS, t As Long
    rdp.dwSize = Len(rdp) + 6
    ChangeBytes List1.Text, rdp.szEntryName

End Sub

Private Sub Command1_Click()
   
    Dial List1.Text

End Sub

Private Function Dial(ByVal Connection As String) As Boolean
    ' дозвон по выбранному соединению
   
    Dim rdp As RASDIALPARAMS, h As Long, resp As Long, str As String, t As Long
   
    rdp.dwSize = Len(rdp) + 6 ' задали размер структуры
    ChangeBytes Connection, rdp.szEntryName 'перевели выбранное имя в байтовый массив и поместили его в структуру RASDIALPARAMS
       
        t = RasGetEntryDialParams(vbNullString, rdp, 0) ' тут можно вытянуть параметры по выбранному соединению.
        ' Однако не вытягиваются ни PhoneNumber, ни UserName...
   
    h = 0 ' обнулили хэндл соединения
        resp = RasDial(0, 0, rdp, 0, 0, h)   'Звоним! Возвращаемый код resp:0-дозвон успешно состоялся;756-Подключение уже выполнено
    Dial = (resp = 0)

End Function

'---------- Вспомогательные функции -------------------------------

Private Function ChangeToStringUni(Bytes() As Byte) As String
    'Трансформируем байтовый массив в UniCode, пригодный для чтения
   
    Dim temp As String
    temp = StrConv(Bytes, vbUnicode)
    ChangeToStringUni = Left(temp, InStr(temp, Chr(0)) - 1)

End Function

Private Function ChangeBytes(ByVal str As String, Bytes() As Byte) As Boolean
    'Трансформируем  строку UniCode в байтовый массив, пригодный для RasAPI- функций
 
    Dim lenBs As Long 'length of the byte array
    Dim lenStr As Long 'length of the string
    lenBs = UBound(Bytes) - LBound(Bytes)
    lenStr = LenB(StrConv(str, vbFromUnicode))
    If lenBs > lenStr Then
        CopyMemory Bytes(0), str, lenStr
        ZeroMemory Bytes(lenStr), lenBs - lenStr
    ElseIf lenBs = lenStr Then
        CopyMemory Bytes(0), str, lenStr
    Else
        CopyMemory Bytes(0), str, lenBs
        ChangeBytes = True
    End If

End Function

[/spoiler]

Спасибо, что дочитали до конца! )). Помогите добрым словом и компетентным советом, пожалуйста!


Яндекс.Метрика Рейтинг@Mail.ru