Jump to content
thomas1972

VBA Script in Powershell überführen, oder Emails aus verzeichnis in Anzahl aufteilen und per Mail versenden

Recommended Posts

Hallo, ich muss ein bestehendes VBA Script in PowerShell umsetzen,

leider habe ich keine Möglichkeit gefunden, dieses über Tools zu realisieren.

Vielleicht kann mir hier jemand helfen.

 

' maximale Anzahl an Anlagen pro Mail
    Const MAXATTACH = 30
    ' Ordner mit den Attachments
    Const ATTACHMENTFOLDER = "C:\temp\Geko Anträge"
    ' Archivordner
    Const ARCHIVEFOLDER = "c:\temp\versendet_Geko_Anträge"
    ' Suchwort für Dateien
    Const SEARCHTERM = "GEKO-Antrag"
    '--------------------------
    ' counter für Attachments
    Dim cnt As Integer: cnt = 0
    Dim colAttachments As Collection
    
    ' Filesystemobject
    Set fso = CreateObject("Scripting.FileSystemObject")
    'Neue Mail nach Vorgabe erstellen
    Set mail = CreateMailTemplate
    ' Attachments suchen ...
    Set colAttachments = SearchFilesInFolder(ATTACHMENTFOLDER, SEARCHTERM)
    'Wenn Attachments da ...
    
    
    If colAttachments.Count > 0 Then
        ' Für jedes Attachment
        For Each File In colAttachments
            ' Wenn max. Attachment-Anzahl erreicht zeige mail und erstelle eine neue
            If cnt > 0 And (cnt Mod MAXATTACH) = 0 Then
                mail.Display
                Set mail = CreateMailTemplate
            End If
            'Attachment hinzufügen
            mail.Attachments.Add File
            'counter erhöhen
            cnt = cnt + 1
        Next
        ' Mail Anzeigen
        mail.Display
        
        ' Dateien in Archivordner verschieben
        For Each File In colAttachments
            'Prüfen ob Dateiname der Vorgabe entspricht  xxxxxxxx_xxxxxxx_GEKO-Antrag_xxxxxxx
             Dim Txt(1) As String
             Dim i As Long
             Dim Match As Boolean
             Set Re = CreateObject("VBScript.RegExp")
             Re.MultiLine = True
             Re.pattern = "\d{8}_\d{7}_GEKO-Antrag_"


                Txt(1) = Right(File, (Len(File) - (Len(ATTACHMENTFOLDER) + 1)))


                For i = 1 To 1
                Match = Re.test(Txt(i))
                     If Match Then
                     fso.MoveFile File, ARCHIVEFOLDER & "\"
                 Else
                     Debug.Print (File), " ---> Fehler, nicht verschoben"
                     End If
                Next
                     
        
            
        Next
            myDebug (File) & " ---> bitte das temp. Verzeichnis auf weitere nicht versendete Dateinen prüfen und bei bedarf umbenennen."

    Else
        ' Keine Attachments gefunden
        MsgBox "Keine Attachments für Suchwort gefunden!", vbExclamation
    End If
    'Cleanup
    Set fso = Nothing
End Sub

 

Edited by thomas1972

Share this post


Link to post

Moin,

 

bitte beschreibe doch dazu, was das Skript genau machen soll und in welchen Anwendungsfällen es genutzt werden soll.

 

Gruß, Nils

 

Share this post


Link to post

Guten Morgen,

 

ich bekomme jeden Tag x Anhänge in ein Verzeichnis gestellt, welche prüft werden müssen. Nach Prüfung sollen diese weitergeleitet werden. Leider kann ich nur eine gewisse Größe an Mails versenden daher ein Limit an Anzahl von Anhängen).

Hier habe ich mir über VBA etwas "gebastelt", was bisher auch immer gut funktionierte, nur wird VBA nicht mehr zulässig sein und ich muss den Umweg über Powershell gehen.

Eigentlich macht das Script folgendes.

Es soll im Verzeichnis C:\temp\Geko Anträge alle Anhänge  in einer Mail versenden, sobald es mehr als 30 Elemente sind, soll eine neue Mail erstellt werden, (jeweils mit maximal 30 Elementen).
-> Sprich füge solange Attachments in der Mail an,  bis die Anzahl von 30 erreicht ist. Sind mehr Elemente im Verzeichnis Vorhanden, erstelle eine weitere Mail

und erzeuge solange x Mails (max 30 Anhängen), bis alle Elemente als Anhang in Mails angefügt wurden und keines mehr im Verzeichnis vorhanden ist.


Im Anschluss sollen die Anhänge welche in der Mail / die Mails angefügt wurden in ein Archiv verschoben werden.

 

Edited by thomas1972

Share this post


Link to post
vor 4 Stunden schrieb thomas1972:
 

Hallo, ich muss ein bestehendes VBA Script in PowerShell umsetzen,

leider habe ich keine Möglichkeit gefunden, dieses über Tools zu realisieren.

Dafür gibt es keine Tools, weil es keinen Sinn macht, VBS-Befehle 1 zu 1 in Powershell zu "übersetzen". 

vor 1 Minute schrieb thomas1972:

.... nur wird VBA nicht mehrlässig sein

was heißt das?

vor 1 Minute schrieb thomas1972:

und ich muss den Umweg über Powershell gehen.

Powershell ist doch kein Umweg!!  ;-) 

vor 2 Minuten schrieb thomas1972:

(jeweils mit maximal 30 Elementen)

... sind 30 Elemente garantiert immer so "klein", dass es auch möglich ist, sie per Anhang mit einer Mail zu vesenden?

vor 5 Minuten schrieb thomas1972:

Es soll im Verzeichnis C:\temp\Geko Anträge alle Anhänge  in einer Mail versenden,

Wäre nicht ein Upload auf einen geschützten Ablage-Ort und eine passende Info-Mail der professionellere Weg?

Share this post


Link to post
vor 15 Minuten schrieb BOfH_666:
vor 16 Minuten schrieb thomas1972:

.... nur wird VBA nicht mehrlässig sein

was heißt das?

es dürfen bei uns keine VBA Scripte mehr ausgeführt werden. Powershell ist die mir einzig gebliebene Möglichkeit gewisse dinge zu automatisieren

 

vor 15 Minuten schrieb BOfH_666:
vor 16 Minuten schrieb thomas1972:

(jeweils mit maximal 30 Elementen)

... sind 30 Elemente garantiert immer so "klein", dass es auch möglich ist, sie per Anhang mit einer Mail zu vesenden?

Ja sind Sie, sollten die Anhänge mal grösser sein, kann ich anhand der Variable die Anzahl noch selbst anpassen

 

vor 15 Minuten schrieb BOfH_666:
vor 16 Minuten schrieb thomas1972:

Es soll im Verzeichnis C:\temp\Geko Anträge alle Anhänge  in einer Mail versenden,

Wäre nicht ein Upload auf einen geschützten Ablage-Ort und eine passende Info-Mail der professionellere Weg?

Leider nein, da die Daten extern verarbeitet werden, ist außer per Mail, kein anderer Austausch möglich. :-(

 

 

Edited by thomas1972

Share this post


Link to post
vor einer Stunde schrieb thomas1972:

Ja sind Sie, sollten die Anhänge mal grösser sein, kann ich anhand der Variable die Anzahl noch selbst anpassen

Wenn Du schon automatisierst, dann richtig. Was ist das Maximum, was Du per Mail versenden darfst / der Empfänger empfangen darf?

vor einer Stunde schrieb thomas1972:

Leider nein, da die Daten extern verarbeitet werden, ist außer per Mail, kein anderer Austausch möglich. :-(

Wie unprofessionell ...  ;-)  :D  .... na dann los ...  wir helfen Dir. :grin3:  Ich vermute mal, dass Du wenigstens die Grundkenntnisse in Powershell bereits erworben hast -  jedenfalls lässt das Deine früher hier gestellte Frage vermuten.  Viele Sachen sind in Powershell deutlich einfacher als in VBS. Wie würdest Du anfangen?

Share this post


Link to post

Ich habe selbst ein wenig mich versucht.

soweit so gut, nur ist wohl die Schleife ein wenig falsch.

 

Es wir der Fehler

"..Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.., .."

genau in der Anzahl des Wert $maxaddachment angezeigt, die darauf zu erstellenden Mails werden sauber erstellt.

Hier als Max Wert 2  = $maxaddachment Anhänge zum testen.

 

Nicht ganz Sauber im Aufbau, ist aber mein zweites mal wie ich mich mit PowerShell auseinander setze
Vielleicht könnt Ihr mir hier behilflich sein?

 cls
#Ausleseverzeichnis tif
$inputDir = "x:\TIFF zum einlesen Scanntool\"

#Pfad mail erfolgreich versendet -File
$move_mail_item = "X:\Sekretariat\"

#Mail Text vorlage
$mailtext = "X:\Textvorlagen\skoda-sekretariat.txt"


$pdfs = get-childitem $inputDir -recurse | where name -like "*GEKO*.tif"

#Anzahl maximler Anhänge je Mail
$maxaddachment = 2


$anzahl= 0
foreach ($pdf in $pdfs) {
    $tif = Join-Path -Path $inputDir -ChildPath ($tifBaseName + '.tif')
    $tif = "" + $pdf
    Write $tif
    

    $tif = $inputDir + $tif
    $pdf_to_move = $inputDir + $tif
   
             if ($anzahl -eq$maxaddachment) {
                $Mail.display()
              
                $ol = New-Object -comObject Outlook.Application  
                $mail = $ol.CreateItem(0)
                $mail.Recipients.Add("xxx@xxx.de")
                $mail.Subject = "Scan Anträge für Archiv"
                $mail.Body = Get-Content -Path $mailtext -Raw
                $anzahl=0
                
                
             }

    if ($anzahl -lt$maxaddachment) {
             $mail.Attachments.Add($tif)
             $anzahl= $anzahl +1
             write $anzahl
             #Move-Item -Path $tif -Destination $move_mail_item

    }
    
  
}

    $Mail.display()
    

 

Edited by thomas1972

Share this post


Link to post

Hmmm ... ich bin ein bissl verwirrt. Du sammelst tif-Dateien ein, nennst die Variable aber $pdfs!? ;-)  In Deiner foreach-Schleife benutzt Du eine Variable $tifBaseName, die aber vorher nicht definiert wird. Erst benutzt Du einmal Join-Path, um einen korrekten Pfad zu erstellen und dann wieder bastelst Du mittels String-Verkettung Pfade zusammen. 

 

Wenn Du Fehlermeldungen erhältst, poste diese doch bitte komplett (auch als Code formatiert bitte). 

Share this post


Link to post

Moin,

 

hm, das ist ziemlich wild ... Tipp: Fang erst mal langsam an und schaff dir die Grundlagen drauf, bevor du so eine recht komplexe Aufgabe angehst.

  • die Benennung von Variablen solltest du deutlicher und einheitlicher vornehmen. Deine Namen geben überhaupt keinen Aufschluss darüber, was du dort speichern willst. Teils sind sie sogar ausdrücklich irreführend. (Und "addachment" ist die plattdeutsche Fassung von "attachment", oder wie? ;-))
  • In der FOR-Schleife stellst du wilde Dinge mit der Variablen $tif an. Du definierst sie mehrfach neu, verwendest sie aber zwischendurch nicht.
  • $mail ist beim ersten Aufruf der Schleife undefiniert, wenn ich es richtig sehe
  • hinter -eq und -lt fehlen Leerzeichen - vielleicht kommt da der Fehler her
  • Statt zwei IF-Schleifen könntest du eine nutzen, die beiden schließen sich ja gegenseitig aus

Und noch ein Vorschlag für eine spätere Ausbaustufe: Es geht doch gar nicht um die Anzahl der Anhänge, sondern um das Volumen, oder? Wäre es eine Möglichkeit, zunächst die Anhänge z.B. in ein Zip-Archiv zu packen und das so lange zu tun, bis das Archiv die Maximalgröße erreicht? Alternativ eben ohne Zip, aber direkt mit den Anhängen. Du könntest in einer Schleife erst mal die "Kandidaten" ermitteln, die die gewünschte Maximalgröße ergeben. (Aber wie gesagt: Spätere Stufe. Mach's erst mal einfach.)

 

Gruß, Nils

 

  • Like 1

Share this post


Link to post

Weil's mich selber interessiert hat ...

 

Hier mal eine Version, die statt des Outlook-Com-Objekts Send-MailMessage benutzt und deshalb auch ohne installiertes Outlook funktionieren würde. ... z.B. vom Server ;-)   

Ich würde auch eher UNC-Pfade als Laufwerksbuchstaben empfehlen.  Also \\Servername\Freigabe anstatt x:\.  ;-) 

 

$maxAttachmentSize  = 20MB
$directory          = 'x:\TIFF zum einlesen Scanntool'
$Filter             = '*GEKO*.tif'
$mailText           = Get-Content -Path 'X:\Textvorlagen\skoda-sekretariat.txt'
$fileList           = [System.Collections.ArrayList](Get-ChildItem -Path $directory -Filter $Filter | Sort-Object -Property Length -Descending )
$attachmentListList = [System.Collections.ArrayList]@()

while ($fileList.count -gt 0) {
    $attachmentList = [System.Collections.ArrayList]@()
    while (($attachmentList.Length + $fileList[0].Length | Measure-Object -Sum).Sum -lt $maxAttachmentSize -and $fileList.count -gt 0) {
        [VOID]$attachmentList.add($fileList[0])
        [VOID]$fileList.RemoveAt(0)
    }
    $index = 1
    while ($fileList.count -gt $index ) {
        if (($attachmentList.Length + $fileList[$index].Length | Measure-Object -Sum).Sum -le $maxAttachmentSize ) {
            [VOID]$attachmentList.add($fileList[$index])
            [VOID]$fileList.RemoveAt($index)
        }
        $index ++
    }
    [VOID]$attachmentListList.Add($attachmentList)
}

foreach ($list in $attachmentListList) {
    $SendMailMessageParams = @{
        From        = 'absender@absender.de'
        To          = 'empfaenger@empfaenger.de'
        Subject     = 'Scan Antraege fuer Archiv'
        Body        = $mailText
        Attachments = $list.FullName
        SmtpServer  = 'smtp.absender.de'
    }
    Send-MailMessage @SendMailMessageParams
}

Bei der maximalen Attachment-Größe musst Du Dich evtl. herantasten weil die Gesamtgröße der Dateien für eine Mail immer ein bissl über der eingestellten Größe liegt (je nach Größe der zuletzt hinzugefügten Datei).

 

Achja ... die "Verschiebe-Aktion" der Dateien in das Archiv-Verzeichnis kannst Du dann hinterher natürlich immernoch machen wenn gewünscht.

 

EDIT:

Ich hab die innere While-Schleife nochmal geändert. Die Summe der Dateigrößen in einer einzelnen "$attachmentList" ist jetzt auf jeden Fall kleiner oder gleich der eingestellten Maximalgröße.

EDIT 2:

Ich hab den Code nochmal ein bissl gepimpt. Jetzt wird die angegebene Maximalgröße optimal ausgenutzt. Das kann - je nach Datei-Anzahl- und Größe - die Anzahl der versendeten Mails reduzieren.

Edited by BOfH_666

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


Werbepartner:



×
×
  • Create New...