Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Работа с переменными окружения Windows. - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: китин, _Boroda_  
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Работа с переменными окружения Windows. (Макросы/Sub)
Работа с переменными окружения Windows.
Alex_ST Дата: Вторник, 29.11.2016, 09:18 | Сообщение № 1
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3199
Репутация: 606 ±
Замечаний: 0% ±

2003
Для передачи данных между приложениями, т.к. необходимые объёмы совсем небольшие (массивы из нескольких коротких стрингов), решил попробовать заюзать переменные окружения Windows
Погуглил, поковырялся в процедурах. Оказывается, это совсем не сложно.
Единственно, что мне не понятно - относительно большое и абсолютно не предсказуемое время создания-чтения-удаления пользовательской переменной окружения.
Для тестирования написал процедурку:
Мало того, что длительности достаточно велики (но для моих целей это не очень критично), но от теста к тесту они ещё и существенно разные. А Длительность чтения вообще иногда показывается отрицательной!
Такое впечатление, что при передаче управления объекту WScript.Shell таймер не только останавливается, но иногда ещё и отматывается обратно. Это как? shock



С уважением,
Алексей
MS Excel 2003 - the best!!!


Сообщение отредактировал Alex_ST - Вторник, 29.11.2016, 09:21
 
Ответить
СообщениеДля передачи данных между приложениями, т.к. необходимые объёмы совсем небольшие (массивы из нескольких коротких стрингов), решил попробовать заюзать переменные окружения Windows
Погуглил, поковырялся в процедурах. Оказывается, это совсем не сложно.
Единственно, что мне не понятно - относительно большое и абсолютно не предсказуемое время создания-чтения-удаления пользовательской переменной окружения.
Для тестирования написал процедурку:
Мало того, что длительности достаточно велики (но для моих целей это не очень критично), но от теста к тесту они ещё и существенно разные. А Длительность чтения вообще иногда показывается отрицательной!
Такое впечатление, что при передаче управления объекту WScript.Shell таймер не только останавливается, но иногда ещё и отматывается обратно. Это как? shock

Автор - Alex_ST
Дата добавления - 29.11.2016 в 09:18
Udik Дата: Вторник, 29.11.2016, 14:39 | Сообщение № 2
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
Сделал засечку через апишку, отрицательного времени нет, хотя ноль тоже озадачивает.
[vba]
Код

Option Explicit

#If VBA7 And Win64 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
Sub test_ENVIROMENT_READ_WRITE()
Dim sEnvType$: sEnvType = "USER" ' "SYSTEM" [default value can be omitted] | "VOLATILE" | "PROCESS" | "USER"
Dim sEnvName$: sEnvName = "myDATA"
Dim sEnvData$: sEnvData = "test-test-test"
Dim lTimer&, t&
With CreateObject("WScript.Shell").Environment(sEnvType)
Debug.Print "Environment(""" & sEnvType & """).Count = " & .Count
    lTimer = Timer
    t = GetTickCount
    .Item(sEnvName) = sEnvData   ' Create User's Environment
Debug.Print "Create Duration = " & Timer - lTimer & " s" ', "Count = " & .Count
Debug.Print "- " & (GetTickCount - t) / 1000 & "s"
Debug.Print "Environment(""" & sEnvType & """).Count = " & .Count
    lTimer = Timer
    t = GetTickCount

    sEnvData = .Item(sEnvName)   ' Read User's Environment
Debug.Print "Read Duration = " & Timer - lTimer & " s", "Value = " & sEnvData
Debug.Print "- " & (GetTickCount - t) / 1000 & "s"

    lTimer = Timer
    t = GetTickCount
    .Remove (sEnvName)   ' Delete User's Environment
Debug.Print "Delete Duration = " & Timer - lTimer & " s" ', "Count = " & .Count
Debug.Print "- " & (GetTickCount - t) / 1000 & "s"
Debug.Print "Environment(""" & sEnvType & """).Count = " & .Count
End With
End Sub

[/vba]


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com


Сообщение отредактировал Udik - Вторник, 29.11.2016, 14:40
 
Ответить
СообщениеСделал засечку через апишку, отрицательного времени нет, хотя ноль тоже озадачивает.
[vba]
Код

Option Explicit

#If VBA7 And Win64 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
Sub test_ENVIROMENT_READ_WRITE()
Dim sEnvType$: sEnvType = "USER" ' "SYSTEM" [default value can be omitted] | "VOLATILE" | "PROCESS" | "USER"
Dim sEnvName$: sEnvName = "myDATA"
Dim sEnvData$: sEnvData = "test-test-test"
Dim lTimer&, t&
With CreateObject("WScript.Shell").Environment(sEnvType)
Debug.Print "Environment(""" & sEnvType & """).Count = " & .Count
    lTimer = Timer
    t = GetTickCount
    .Item(sEnvName) = sEnvData   ' Create User's Environment
Debug.Print "Create Duration = " & Timer - lTimer & " s" ', "Count = " & .Count
Debug.Print "- " & (GetTickCount - t) / 1000 & "s"
Debug.Print "Environment(""" & sEnvType & """).Count = " & .Count
    lTimer = Timer
    t = GetTickCount

    sEnvData = .Item(sEnvName)   ' Read User's Environment
Debug.Print "Read Duration = " & Timer - lTimer & " s", "Value = " & sEnvData
Debug.Print "- " & (GetTickCount - t) / 1000 & "s"

    lTimer = Timer
    t = GetTickCount
    .Remove (sEnvName)   ' Delete User's Environment
Debug.Print "Delete Duration = " & Timer - lTimer & " s" ', "Count = " & .Count
Debug.Print "- " & (GetTickCount - t) / 1000 & "s"
Debug.Print "Environment(""" & sEnvType & """).Count = " & .Count
End With
End Sub

[/vba]

Автор - Udik
Дата добавления - 29.11.2016 в 14:39
Alex_ST Дата: Вторник, 29.11.2016, 15:22 | Сообщение № 3
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3199
Репутация: 606 ±
Замечаний: 0% ±

2003
Проверил с системным таймером через GetTickCount ( с возможностью VBA7 And Win64 заморачиваться не стал, т.к. у меня это не бывает никогда)
Непонятно, почему время разное получается? И, таки-да, нулевое время реально напрягает shock
К стати, Евгений, в зачем ты добавил - в Debug.Print перед системным таймером? :) Не понял, поэтому убрал, чтобы глаз не мозолило.



С уважением,
Алексей
MS Excel 2003 - the best!!!


Сообщение отредактировал Alex_ST - Вторник, 29.11.2016, 16:40
 
Ответить
СообщениеПроверил с системным таймером через GetTickCount ( с возможностью VBA7 And Win64 заморачиваться не стал, т.к. у меня это не бывает никогда)
Непонятно, почему время разное получается? И, таки-да, нулевое время реально напрягает shock
К стати, Евгений, в зачем ты добавил - в Debug.Print перед системным таймером? :) Не понял, поэтому убрал, чтобы глаз не мозолило.

Автор - Alex_ST
Дата добавления - 29.11.2016 в 15:22
Udik Дата: Вторник, 29.11.2016, 15:42 | Сообщение № 4
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
зачем ты добавил - в Debug.Print перед системным таймером

чтоб строчку не спутать :)


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com
 
Ответить
Сообщение
зачем ты добавил - в Debug.Print перед системным таймером

чтоб строчку не спутать :)

Автор - Udik
Дата добавления - 29.11.2016 в 15:42
Alex_ST Дата: Вторник, 29.11.2016, 16:48 | Сообщение № 5
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3199
Репутация: 606 ±
Замечаний: 0% ±

2003
Но вообще-то, поковырявшись, много нового узнал о работе с переменными окружения.
Например, то, что есть разные типы, но для самостоятельного использования доступны только переменные типа User
Также то, что имена переменных уникальны только внутри типа.
В общем, слепил процедурку, которая на лист выводит перечень всех переменных окружения, их типы и значения.
Может быть кому-нибудь пригодится:



С уважением,
Алексей
MS Excel 2003 - the best!!!


Сообщение отредактировал Alex_ST - Вторник, 29.11.2016, 16:52
 
Ответить
СообщениеНо вообще-то, поковырявшись, много нового узнал о работе с переменными окружения.
Например, то, что есть разные типы, но для самостоятельного использования доступны только переменные типа User
Также то, что имена переменных уникальны только внутри типа.
В общем, слепил процедурку, которая на лист выводит перечень всех переменных окружения, их типы и значения.
Может быть кому-нибудь пригодится:

Автор - Alex_ST
Дата добавления - 29.11.2016 в 16:48
sboy Дата: Вторник, 29.11.2016, 17:07 | Сообщение № 6
Группа: Друзья
Ранг: Участник клуба
Сообщений: 2566
Репутация: 724 ±
Замечаний: 0% ±

Excel 2010
Alex_ST, так есть же в VBA функция Environ (или это не то же самое?)
[vba]
Код
Sub env()
For x = 1 To 37 'для Windows 7
Cells(x, 1).Value = Environ(x)
Next x
End Sub
[/vba]


Яндекс: 410016850021169
 
Ответить
СообщениеAlex_ST, так есть же в VBA функция Environ (или это не то же самое?)
[vba]
Код
Sub env()
For x = 1 To 37 'для Windows 7
Cells(x, 1).Value = Environ(x)
Next x
End Sub
[/vba]

Автор - sboy
Дата добавления - 29.11.2016 в 17:07
Udik Дата: Вторник, 29.11.2016, 17:34 | Сообщение № 7
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
или это не то же самое?

Так она только читает.


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com
 
Ответить
Сообщение
или это не то же самое?

Так она только читает.

Автор - Udik
Дата добавления - 29.11.2016 в 17:34
Alex_ST Дата: Вторник, 29.11.2016, 22:05 | Сообщение № 8
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3199
Репутация: 606 ±
Замечаний: 0% ±

2003
есть же в VBA функция Environ
А сколько переменных выводит Environ и сколько CreateObject("WScript.Shell").Environment(sEnvType) Вы видели?
Да и, как правильно сказал Udik, Environ только читает переменные. Это я и сам давно выяснил, потому и закопался в Environment
Но вопрос со странным временем работы с Environment так и остался открытым...



С уважением,
Алексей
MS Excel 2003 - the best!!!


Сообщение отредактировал Alex_ST - Вторник, 29.11.2016, 22:10
 
Ответить
Сообщение
есть же в VBA функция Environ
А сколько переменных выводит Environ и сколько CreateObject("WScript.Shell").Environment(sEnvType) Вы видели?
Да и, как правильно сказал Udik, Environ только читает переменные. Это я и сам давно выяснил, потому и закопался в Environment
Но вопрос со странным временем работы с Environment так и остался открытым...

Автор - Alex_ST
Дата добавления - 29.11.2016 в 22:05
Udik Дата: Среда, 30.11.2016, 13:56 | Сообщение № 9
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
Я тут нашёл как переменные через апишки читать/устанавливать, вроде быстрее получается.
[vba]
Код

Option Explicit

#If VBA7 And Win64 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
Private Declare PtrSafe Function SetEnvironmentVariable Lib "kernel32" Alias "SetEnvironmentVariableA" (ByVal lpName As String, ByVal lpValue As String) As Long
Private Declare PtrSafe Function GetEnvironmentVariable Lib "kernel32" Alias "GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function SetEnvironmentVariable Lib "kernel32" Alias "SetEnvironmentVariableA" (ByVal lpName As String, ByVal lpValue As String) As Long
Private Declare Function GetEnvironmentVariable Lib "kernel32" Alias "GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
#End If

Sub test_ENVIROMENT_READ_WRITE2()
Dim t As Long
t = GetTickCount
SetEnvironmentVariable "NLS1_LANG", "test: AMERICAN_AMERICA.CL8MSWIN1251" 'установка переменной
Debug.Print GetEnvironmentVar("NLS1_LANG") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
t = GetTickCount
SetEnvironmentVariable "NLS1_LANG", "test: =========" 'установка переменной
Debug.Print GetEnvironmentVar("NLS1_LANG") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
t = GetTickCount
SetEnvironmentVariable "test", "test: 111111111" 'установка переменной
Debug.Print GetEnvironmentVar("test") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
t = GetTickCount
SetEnvironmentVariable "test", "test: ************" 'установка переменной
Debug.Print GetEnvironmentVar("test") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
End Sub

'===

Function GetEnvironmentVar(sName As String) As String
    GetEnvironmentVar = String(255, 0)
    GetEnvironmentVariable sName, GetEnvironmentVar, Len(GetEnvironmentVar)
    If InStr(1, GetEnvironmentVar, Chr$(0)) > 0 Then GetEnvironmentVar = Left$(GetEnvironmentVar, InStr(1, GetEnvironmentVar, Chr$(0)) - 1)
    GetEnvironmentVar = sName + ": " + GetEnvironmentVar
End Function

[/vba]

Только как удалять не знаю :) .
К сообщению приложен файл: API_enviroment.xlsm (17.1 Kb)


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com


Сообщение отредактировал Udik - Среда, 30.11.2016, 14:04
 
Ответить
СообщениеЯ тут нашёл как переменные через апишки читать/устанавливать, вроде быстрее получается.
[vba]
Код

Option Explicit

#If VBA7 And Win64 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
Private Declare PtrSafe Function SetEnvironmentVariable Lib "kernel32" Alias "SetEnvironmentVariableA" (ByVal lpName As String, ByVal lpValue As String) As Long
Private Declare PtrSafe Function GetEnvironmentVariable Lib "kernel32" Alias "GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function SetEnvironmentVariable Lib "kernel32" Alias "SetEnvironmentVariableA" (ByVal lpName As String, ByVal lpValue As String) As Long
Private Declare Function GetEnvironmentVariable Lib "kernel32" Alias "GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
#End If

Sub test_ENVIROMENT_READ_WRITE2()
Dim t As Long
t = GetTickCount
SetEnvironmentVariable "NLS1_LANG", "test: AMERICAN_AMERICA.CL8MSWIN1251" 'установка переменной
Debug.Print GetEnvironmentVar("NLS1_LANG") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
t = GetTickCount
SetEnvironmentVariable "NLS1_LANG", "test: =========" 'установка переменной
Debug.Print GetEnvironmentVar("NLS1_LANG") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
t = GetTickCount
SetEnvironmentVariable "test", "test: 111111111" 'установка переменной
Debug.Print GetEnvironmentVar("test") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
t = GetTickCount
SetEnvironmentVariable "test", "test: ************" 'установка переменной
Debug.Print GetEnvironmentVar("test") ' чтение переменной
Debug.Print "= " & (GetTickCount - t) / 1000 & "s"
End Sub

'===

Function GetEnvironmentVar(sName As String) As String
    GetEnvironmentVar = String(255, 0)
    GetEnvironmentVariable sName, GetEnvironmentVar, Len(GetEnvironmentVar)
    If InStr(1, GetEnvironmentVar, Chr$(0)) > 0 Then GetEnvironmentVar = Left$(GetEnvironmentVar, InStr(1, GetEnvironmentVar, Chr$(0)) - 1)
    GetEnvironmentVar = sName + ": " + GetEnvironmentVar
End Function

[/vba]

Только как удалять не знаю :) .

Автор - Udik
Дата добавления - 30.11.2016 в 13:56
krosav4ig Дата: Среда, 30.11.2016, 17:04 | Сообщение № 10
Группа: Друзья
Ранг: Старожил
Сообщений: 2346
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
как удалять
еси мне память не изменяет, то [vba]
Код
SetEnvironmentVariable "test", Empty 'удаление переменной
[/vba]по крайней мере в Басике было так [vba]
Код
Success := SetEnvironmentVariable(PChar(VarName), nil)
[/vba]
а быстрее, имхо, потому, что создаются переменные процесса, а не системные, как было с WScript.Shell


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4ig - Среда, 30.11.2016, 17:09
 
Ответить
Сообщение
как удалять
еси мне память не изменяет, то [vba]
Код
SetEnvironmentVariable "test", Empty 'удаление переменной
[/vba]по крайней мере в Басике было так [vba]
Код
Success := SetEnvironmentVariable(PChar(VarName), nil)
[/vba]
а быстрее, имхо, потому, что создаются переменные процесса, а не системные, как было с WScript.Shell

Автор - krosav4ig
Дата добавления - 30.11.2016 в 17:04
Alex_ST Дата: Вторник, 06.12.2016, 11:01 | Сообщение № 11
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3199
Репутация: 606 ±
Замечаний: 0% ±

2003
А феномен отрицательного времени по таймеру мне на Планете объяснили: я, оказывается лоханулся и значение, получаемое от Timer запихивал в переменную Long вместо Single :'(
Вот при округлении близкого к нулю значения лажа и получалась.



С уважением,
Алексей
MS Excel 2003 - the best!!!
 
Ответить
СообщениеА феномен отрицательного времени по таймеру мне на Планете объяснили: я, оказывается лоханулся и значение, получаемое от Timer запихивал в переменную Long вместо Single :'(
Вот при округлении близкого к нулю значения лажа и получалась.

Автор - Alex_ST
Дата добавления - 06.12.2016 в 11:01
Alex_ST Дата: Вторник, 06.12.2016, 12:52 | Сообщение № 12
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3199
Репутация: 606 ±
Замечаний: 0% ±

2003
Udik, попробовал я-таки твой пример с API-шным обращением.
Скорость, конечно, впечатляет. И то, что переменные создаются процессные (PROCESS), а не пользовательские (USER), а потому их нет необходимости удалять, т.к. сами умирают после перезапуска Excel - это отлично.
Но до чего же не люблю я API %) Их в отличие от VBA запомнить невозможно, а нужно тупо как иероглифы из справочника дёргать. Да и процедуры с их использованием получаются размазанными по всему модулю: сама процедура в одном месте листинга, а API-шки для неё - в декларациях. Копирнёшь куда-нибудь процедуру, а про декларации забудешь...



С уважением,
Алексей
MS Excel 2003 - the best!!!
 
Ответить
СообщениеUdik, попробовал я-таки твой пример с API-шным обращением.
Скорость, конечно, впечатляет. И то, что переменные создаются процессные (PROCESS), а не пользовательские (USER), а потому их нет необходимости удалять, т.к. сами умирают после перезапуска Excel - это отлично.
Но до чего же не люблю я API %) Их в отличие от VBA запомнить невозможно, а нужно тупо как иероглифы из справочника дёргать. Да и процедуры с их использованием получаются размазанными по всему модулю: сама процедура в одном месте листинга, а API-шки для неё - в декларациях. Копирнёшь куда-нибудь процедуру, а про декларации забудешь...

Автор - Alex_ST
Дата добавления - 06.12.2016 в 12:52
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Работа с переменными окружения Windows. (Макросы/Sub)
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!