umgebungsvariable setzen per VBA in 64bit


Betrifft: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 14.03.2019 09:16:29

Hallo Allerseits,
zunächst einmal ein großes Danke für dieses Forum mit den vielen hilfreichen Infos und nützlichen Hilfestellungen!

Hier in kurz meine Problemstellung für die ich Hilfe benötige:


Wie kann ich aus VBA Umgebungsvariablen setzen?
Ich habe im Internet bereits Anleitungen gefunden, aber die scheinen alle nur für 32bit zu funktionieren. Da ich aber sowohl Windows als auch Office in 64 bit habe, funktionieren diese Lösungen bei mir nicht.

Private Declare Function SetEnvironmentVariable _
Lib "kernel32.dll" _
Alias "SetEnvironmentVariableA" ( _
ByVal lpName As String, _
ByVal lpValue As String _
) As Long
Public Sub SetVar(strName As String, strValue As String)
Call SetEnvironmentVariable(strName, strValue)
End Sub
(ab hier der Kontext dazu, falls das relevant ist)
Ich habe ein Macro programmiert, das in Excel Seiten erstellt, die dann in ein PDF mit integriertem Briefpapier exportiert werden sollen.
Ich nutze dafür den PDF24 Drucker.
Für die vollständige Automatisierung fehlt mir jetzt nur noch der Schritt, dass ich den Namen der PDF Datei irgendwie per VBA bestimmen kann (einfach nur als PDF speichern geht meines Wissens nicht, weil es dabei dann nicht die Funktion mit dem Briefpapier gibt wie bei PDF24). Ich habe rausgefunden, dass man bei PDF24 das so einstellen kann, dass in den Namen eine Umgebungsvariable eingesetzt wird. Daher wollte ich es so lösen, dass vba den Namen in solch eine Variable schreibt.
Vielen Dank im Voraus!
Leo

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Nepumuk
Geschrieben am: 14.03.2019 09:23:30
Hallo Leo,
versuch es mal so:

Private Declare PtrSafe Function SetEnvironmentVariableA Lib "kernel32.dll" ( _
    ByVal lpName As String, _
    ByVal lpValue As String) As Long
Public Sub SetVar(strName As String, strValue As String)
    Call SetEnvironmentVariableA(strName, strValue)
End Sub

Gruß
Nepumuk

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 18.03.2019 09:58:03
Hallo Nepumuk, vielen Dank für die Antwort.
Ich habe jetzt folgendes ausprobiert:

Private Declare PtrSafe Function SetEnvironmentVariableA Lib "kernel32.dll" (ByVal lpName As  _
String, ByVal lpValue As String) As Long
Public Sub SetVar(strName As String, strValue As String)
    Call SetEnvironmentVariableA(strName, strValue)
End Sub
Sub varsetzen()
 SetVar dateiname, "test"
End Sub

Dann habe ich varsetzen per F5 Taste ausgeführt. Dann kommt folgender Fehler:
"Fehler beim Kompilieren:
Nach End Sub, End Function oder End Property können nur Kommentare stehen"

dann wird die erste Zeile ("private declare....") markiert.
Hab ich da jetzt was bestimmtes übersehen oder hängt das mit dem ursprünglichen Problem zusammen?
Liebe Grüße,
Leo

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Nepumuk
Geschrieben am: 18.03.2019 12:12:28
Hallo Leo,
die Zeile: Private Declare PtrSafe Function... muss oberhalb von allen Prozeduren im Modul stehen.
Gruß
Nepumuk

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 18.03.2019 12:24:23
ah, ok danke, das wusste ich nicht.
Jetzt hab ichs nochmal probiert, jetzt kommt der Fehler

"Fehler beim Kompilieren:
Argumenttyp ByRef unverträglich"


Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 18.03.2019 12:25:24
(markiert wird dann

Sub varsetzen()
)

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Nepumuk
Geschrieben am: 18.03.2019 12:34:31
Hallo Leo,
die "Variable" Dateiname ist nicht deklariert. Wenn das der Name der Umgebungsvariablen sein soll, dann musst du sie in Anführungszeichen setzen.
Gruß
Nepumuk

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 18.03.2019 12:33:11
oh, ich hatte die Anführungszeichen vergessen...
Jetzt kommen keine Fehlermeldungen mehr. Wenn ich allerdings in der Eingabeaufforderung mit dem Befehl set die Umgebungsvariablen anschaue, ist meine Variable dort nicht zu finden...

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Nepumuk
Geschrieben am: 18.03.2019 15:37:50
Hallo Leo,
ich hab mal nachgeschaut. Um eine neue Umgebungsvariable zu erzeugen ist etwas mehr Aufwand notwendig.
Teste mal:

Option Explicit

Private Declare PtrSafe Function SetEnvironmentVariableA Lib "kernel32.dll" ( _
    ByVal lpName As String, _
    ByVal lpValue As String) As Long
Private Declare PtrSafe Function SHSetValueA Lib "shlwapi.dll" ( _
    ByVal hKey As Long, _
    ByVal pszSubKey As String, _
    ByVal pszValue As String, _
    ByVal dwType As Long, _
    ByRef pvData As String, _
    ByVal cbData As Long) As Long
Private Declare PtrSafe Function SendMessageTimeoutA Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal msg As Long, _
    ByVal wParam As LongPtr, _
    ByVal lParam As String, _
    ByVal fuFlags As Long, _
    ByVal uTimeout As Long, _
    ByRef lpdwResult As LongPtr) As LongPtr

Private Const REG_EXPAND_SZ As Long = 2
Private Const HWND_BROADCAST As LongPtr = &HFFFF&
Private Const WM_WININICHANGE As Long = &H1A
Private Const HKEY_CURRENT_USER As Long = &H80000001
Private Const SMTO_ABORTIFHUNG As Long = &H2

Private Sub SetEnvironmentVar(ByVal strEnvName As String, ByVal strEnvValue As String)
    Dim lngptrReturn As LongPtr
    Call SetEnvironmentVariableA(strEnvName, strEnvValue)
    lngptrReturn = SHSetValueA(HKEY_CURRENT_USER, "Environment", strEnvName, REG_EXPAND_SZ, _
        ByVal strEnvValue, LenB(StrConv(strEnvValue, vbFromUnicode)) + 1)
    Call SendMessageTimeoutA(HWND_BROADCAST, WM_WININICHANGE, 0, _
        "Environment", SMTO_ABORTIFHUNG, 5000, lngptrReturn)
End Sub

Public Sub Main()
    Const ENV_VAR_NAME As String = "dateiname"
    Const ENV_VAR_VALUE As String = "Test"
    Call SetEnvironmentVar(ENV_VAR_NAME, ENV_VAR_VALUE)
End Sub

Voraussetzung ist, du hast schreibenden Zugriff auf die Registry.
Gruß
Nepumuk

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 18.03.2019 15:41:52
super, das funktioniert. vielen Dank!!

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 18.03.2019 18:00:37
doch noch eine Frage dazu: Wie kann ich machen, dass ich auf diese Function von anderen Projekten/Modulen aus zugreifen kann?
Ich habe alle Private und Dim durch Public ersetzt, aber leider kommt dennoch die Fehlermeldung "Sub oder Function nicht definiert" wenn ich versuche sie aus einem anderen Projekt heraus aufzurufen.
LG Leo

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Nepumuk
Geschrieben am: 18.03.2019 19:42:30
Hallo Leo,
Sub's in anderen Projekten kannst du nur per Application.Run - Methode aufrufen.
Gruß
Nepumuk

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 18.03.2019 20:13:52
ok vielen Dank.
Gibt es eigentlich unterschiedliche Arten von Umgebungsvariablen? Ich habe nämlich nun eine eigene Umgebungsvariable mit VBA erstellt und kann diese über cmd -> set auch sehen

HNDateiname=Test

aber wenn ich mit PDF24 eine Datei abspeichere passiert nichts, wobei es mit anderen Umgebungsvaiablen einwandfrei funktioniert. z.B. mit %USERNAME% oder %yoticvar% (letztere hatte ich mal per VBScript oder so erstellt, also ist es auch eine eigene). Nur die aus VBA nimmt er irgendwie nicht...

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Nepumuk
Geschrieben am: 19.03.2019 06:52:36
Hallo Leo,
keine Ahnung. Ich stell die Frage auf offen.
Gruß
Nepumuk

Betrifft: AW: umgebungsvariable setzen per VBA in 64bit
von: Leo
Geschrieben am: 19.03.2019 11:33:54
kann es sein, dass die erst nach einem Neustart irgendwo anders eingelesen werden oder so?
Falls jemand eine Idee hat, wie man das umgehen kann wäre ich sehr dankbar, weil falls ein Neustart erforderlich wäre, wäre ja die ganze Automatisierung hinfällig...
LG Leo

Excel-Beispiele zum Thema "umgebungsvariable setzen per VBA in 64bit"