stehe vor einer mir schwierig vorkommenden Herausforderung.
Ich versuche aus einer Excel Arbeitsmappe eine Mail zu generieren, das funktioniert grundsätzlich, nur sieht diese Liste in etwa so aus.
Diese Liste ändert sich aber ständig (Jede Woche ca.) und somit hat sie keine feste Formatierung wie sie aussieht.
Ich möchte also irgendwie an den Zuständigen Sachbearbeiter eine Mail generieren mit dem Inhalt der Excel Tabelle (Einfach Kopieren).
Also müsste ich irgendwie dem Makro sagen, dass es solange den Bereich kopiert bis ein neuer Sachbearbeiter auftritt.
Soweit bin ich Gedanklich ja schon nur die Umsetzung fehlt.
Habt ihr da vlt. eine Idee oder gar eine Lösung?
Freue mich auf Rückmeldung
danke für die schnelle Rückmeldung.
Die Liste nach Sachbearbeitern zu Filtern mache ich bereits.
Ich kann dir leider bei Punkt 2 nicht ganz folgen was du mit "Filtrat" meinst.
Ich schau mir mal die Funktion RangeToHtml an bisher habe ich davon noch kein Gebrauch gemacht.
Wenn du vlt. einen kleinen Beispiel Code hättest wäre mir sehr Geholfen.
Okay dass verstehe ich soweit.
Aber ungeklärt ist noch ob dieser Vorgang auch Automatisch für jeden Sachbearbeiter geht.
Heißt also:
Liste wird aus einer SQL abfrage Erstellt -> Makro soll ausgeführt werden -> Liste soll nach Sachbearbeiter gefiltert werden -> E-Mail's an alle Sachbearbeiter mit Inhalt senden -> Mappe Schließen
aber da diese Liste Woche für Woche anders aussehen kann bin ich am Rätseln wie ich es schaffe dies so hinzubekommen.
Noch besser, falls du via ADODB auf die Datenbank aus Excel zugreifen kannst:
a) Array an Sachbearbeiter definieren
b) Recordset mit Sachbearbeiter-manipuliertem SQL-Statement aus einer Schleife absetzen
c) Rückgabewert des Recordset in ein Array -> bzw .Body der Message
Et violà !
Falls kein ADODB:
a) Menge an Sachbearbeiter definieren (also Nummern)
b) Nummern in einer Schleife als Filter setzen
c) prüfen ob Filtrat Daten enthält
d) weiter mit Post #2 ab b)
Leider sagt mir ADODB nichts....vlt. such ich mal danach und kann es dann iwie zusammenbasteln.
Die Lösung mit der Schleife hört sich bisher sehr gut an zusammen mit einer prüfung ob text vorhanden ist sollte dies kein problem sein.
Gibt es möglicherweise einen einfacheren weg eine E-Mail zu generieren? Müsste mir das RangeToHtml erstmal anschauen.
hab dir die Test Excelmappe angehängt.
Projektdaten Test.xlsx (Größe: 10,82 KB / Downloads: 5)
Die versendung der Mails sollte über Outlook stattfinden.
Option Explicit
Private olApp As Object
Private olMail As Object
Const m_sWksFilter As String = "E-Mails"
Const m_sWksProjektdaten As String = "Projektdaten"
Sub IceSlayer()
Dim wkb As Workbook
Dim wks As Worksheet, wksProjektdaten As Worksheet
Dim arr() As Variant
Dim rng As Range, rngHTML As Range
Dim i As Long
'
On Error GoTo err
'
Call TurnOffFunctionality
'
Set wkb = ThisWorkbook
Set wks = wkb.Worksheets(m_sWksFilter)
Set wksProjektdaten = wkb.Worksheets(m_sWksProjektdaten)
'
'Sachbearbeiter in Array
With wks
Set rng = .Range(.Cells(2, 1), .Cells(.Cells(.Rows.Count, 2).End(xlUp).Row, 2))
arr = rng
End With
'
'Filter setzen
With wksProjektdaten
If .AutoFilterMode = True Then
.AutoFilter.ShowAllData
ElseIf .AutoFilterMode = False Then
.Range("A1").AutoFilter
End If
End With
'
'Range nach Sachbearbeiter sortieren
Call SortAutoFilter(wksProjektdaten, wksProjektdaten.Range("D1:D19"))
'
'Emails erzeugen; .Display
For i = LBound(arr, 1) To UBound(arr, 1) Step 1
With wksProjektdaten
'Range nach Sachbearbeiter filtern
.Range("A1").AutoFilter Field:=4, Criteria1:=arr(i, 1)
'prüfen, ob Filterergebnis leer
Set rngHTML = .AutoFilter.Range.SpecialCells(xlCellTypeVisible)
With rngHTML
If .Cells.Count > 4 Then 'nur überschrift = 4; sonst vielfaches von 4
Call createMails(rngHTML, arr(i, 2))
End If
End With
.ShowAllData
End With
Next
'
err:
If err.Number <> 0 Then
MsgBox err.Number & vbCrLf & err.Description
End If
Call TurnOnFunctionality
Set wks = Nothing: Set wksProjektdaten = Nothing: Set wkb = Nothing: Set olMail = Nothing: Set olApp = Nothing
End Sub
Sub SortAutoFilter(wks As Worksheet, rngSort As Range)
With wks
.AutoFilter.Sort.SortFields.Clear
.AutoFilter.Sort.SortFields.Add Key _
:=rngSort, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
End With
With wks.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2016
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Sub createMails(rng As Range, ByVal sRecipient As String)
'
On Error Resume Next
'
Set olApp = GetObject(, "Outlook.Application")
If err.Number = 429 Then
err.Clear
Set olApp = CreateObject("Outlook.Application")
If err.Number = 429 Then
err.Clear
MsgBox "Excel installiert ?", vbCritical + vbOKOnly, "Author informiert:"
Exit Sub
End If
End If
'
Set olMail = olApp.CreateItem(olMailItem)
With olMail
.To = sRecipient
.HTMLBody = RangetoHTML(rng)
.Display
End With
End Sub
Public Sub TurnOffFunctionality()
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False
Application.EnableEvents = False
Application.ScreenUpdating = False
End Sub
Public Sub TurnOnFunctionality()
Application.Calculation = xlCalculationAutomatic
Application.DisplayStatusBar = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub