ValidateFieldFlag
OnAfterLogOn OnCurrentContactChanged
FileDatabaseTemplates
true
13;18;20;21;22
de;en
' #ScriptName: ValidateFieldFlag
' Funktion:
' #Description: Überprüft Inhalte eines Feldes der aktuellen Entität/Datensatz und setzt dementsprechend eine Flage in einem Bild-Element im Layout.
' Fehler werden in die Act! Log-Datei geschrieben!
' #Author: Julien Temole, jt@melville-schellmann.de; Robert Schellmann, rs@act7.de
' #Copyright: © 2014-2020 by Melville-Schellmann
' #Version; 1.0.3 (19.08.2020) Unterstützung aller Detailansichten. Entprellung mit einem DelayTimer beim Auftreten von mehrfachen Events, wie z.B. beim Wechseln von der Kontaktliste zu einem Kontakt. Hierbei wird drei mal der Event ContactChanged gefeuert.
' #Version: 1.0.2 (02.07.2019) Klasse BlinkTimer für Tooltiptext und Blinkfunktion hinzugefügt
' #Version: 1.0.1 (01.07.2019) Erweiterung auf alle Detailansichten
' #Version: 1.0.0 (30.04.2014) s.o
' AddReference("Melville_Schellmann.ACTOptimum3.Control.AutoData3")
'Shared Variablen Initialisierungen-------------------------------------------------------------------------------------------------------------------------------
m_sScriptName = "ValidateFieldFlag"
m_oError = New ErrorHandling.BaseErrorMessage
m_oACTApp = ACTApp
m_oAutodata = New Melville_Schellmann.ACTOptimum3.Control.AutoData3.AutoDataScript(m_oACTApp, Nothing, ActGlobal.ActRegion.Contact, True)
'-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Dim sMinimumVersion As String = "6.0.7207.20688" ' Diese Version vom ACTOptimum ist mindestens nötig für diesen AutoDataPatch
' Initiiert den DelayTimer, er wird verwendet um schnell aufeinander folgende Ereignisse zu 'entprellen'. So dass die Validierung der aktuellen Entitäts erst am Ende eine Ereignisfolge ausgeführt wird.
If m_oDelayTimer Is Nothing Then
m_oDelayTimer = New system.Windows.Forms.Timer
m_oDelayTimer.Enabled = False
m_oDelayTimer.Interval = 400
AddHandler m_oDelayTimer.Tick, AddressOf DelayTimer_Ticked
End If
' Überprüfung der einzelnen möglichen Ereignisse
Select Case ACTOptimum.ACTPatcher.AutoDataPatcher.LastFiredACTEvent
Case Melville_Schellmann.ACTOptimum6.Plugin.Patch.enmACTEvent.OnAfterLogOn
' Hier könnte Code für das Ereigniss "nach der Datenbankanmeldung" stehen
If Not IsVersionOrHigher(m_oAutodata.ACTOptimum.ProductVersion, sMinimumVersion) Then
Msgbox(String.Format("Der AutoDataPatch '{0}' benötigt vom ACTOptimum mindestens die Version '{1}'." & vbcrlf & "Aktuell ist die Version '{2}.{3}.{4}.{5}' installiert.", m_sScriptName, sMinimumVersion, m_oAutodata.ACTOptimum.ProductVersion.Major, m_oAutodata.ACTOptimum.ProductVersion.Minor, m_oAutodata.ACTOptimum.ProductVersion.Build, m_oAutodata.ACTOptimum.ProductVersion.Revision), MsgBoxStyle.Exclamation, m_sScriptName)
GoTo Abbruch
End If
Case Melville_Schellmann.ACTOptimum6.Plugin.Patch.enmACTEvent.OnAfterLogOff
' Hier könnte Code für das Ereigniss "nach dem Abmelden von der Datenbank" stehen
Case Else
' Dieser Code wird bei allen übrigen Ereignissen ausgeführt
' wie z.B. "Der aktuelle Kontakt wurde gewechselt"
If Not IsVersionOrHigher(m_oAutodata.ACTOptimum.ProductVersion, sMinimumVersion) Then
GoTo Abbruch
End If
' Den aktuellen Datensatz ermitteln
Dim oCurrentEntity As Act.Framework.MutableEntities.MutableEntity
Dim lCurrentEntityType As ActGlobal.ActRegion
If TryGetCurrentEntityAndEntityType(oCurrentEntity, lCurrentEntityType) = True Then
' Es wird der DelayTimer gestartet
' Wenn die Intervallzeit (400 ms) abgelaufen ist wird die Funktion DelayTimer_Ticked ausgeführt
' Innerhalb dieser Zeitspanne auftretene Ereignisse verlängern/verschieben den Zeitpunkt.
'PrintError("Start DelayTimer.", m_sScriptName)
If m_oDelayTimer.Enabled = False Then
m_oDelayTimer.Enabled = True
End If
m_oDelayTimer.Stop
m_oDelayTimer.Start
End If
End Select
Abbruch:
If m_oError.HasAnError Then
'm_oError.ShowError(MsgBoxStyle.Exclamation, m_sScriptName)
PrintError(m_oError.ErrorMessage, m_sScriptName)
End If
End Sub
Private Shared m_oACTApp As Act.UI.ActApplication
Private Shared m_oError As ErrorHandling.BaseErrorMessage
Private Shared m_sScriptName As String
Private Shared m_oAutodata As Melville_Schellmann.ACTOptimum3.Control.AutoData3.AutoDataScript
Private Shared m_oBlinkTimer As BlinkTimer
Private Shared m_oDelayTimer As System.Windows.Forms.Timer
Private Shared Sub DelayTimer_Ticked(sender As Object, e As EventArgs)
Dim oDelayTimer As System.Windows.Forms.Timer
oDelayTimer = CType(sender, System.Windows.Forms.Timer)
oDelayTimer.Stop
oDelayTimer.Enabled = False
Dim sFieldName As String = "Newsletter-Verteiler" 'Name des Feldes, dessen Inhalt überprüft wird
Dim sPictureName As String = "picFlagXY" ' Name des im Layout vordefinierten Bildcontainers (Kein Bildfeld!)
Dim oCurrentEntity As Act.Framework.MutableEntities.MutableEntity
Dim lCurrentEntityType As ActGlobal.ActRegion
Dim oFlagPic As System.Windows.Forms.PictureBox
' Sicher stellen dass das Patch nur in einer der Detail-Ansichten ausgeführt wird und die aktuelle Entität ermitteln.
If TryGetCurrentEntityAndEntityType(oCurrentEntity, lCurrentEntityType) = False Then
GoTo Abbruch
End If
' Sucht nach dem Picturebox-Control
If TryGetControl(m_oACTApp.CurrentView, sPictureName, GetType(System.Windows.Forms.PictureBox), oFlagPic) = False Then
m_oError.SetError("Im Layout konnte kein Bildelement mit dem Namen '{0}' gefunden werden." & System.Environment.NewLine & _
"Bitte legen Sie ein Bildelement (Pictorebox, kein Bildfeld) mit dem Namen '{0}' im Layout an.", sPictureName)
GoTo Abbruch
End If
' Die Entitätswerte validieren und eventuell das Bild im FlagPic anpassen.
If TryValidateEntity(oCurrentEntity, lCurrentEntityType, sFieldName, oFlagPic) = False Then
GoTo Abbruch
End If
Abbruch:
If m_oError.HasAnError Then
' m_oError.ShowError(MsgBoxStyle.Exclamation, m_sScriptName)
PrintError(m_oError.ErrorMessage, m_sScriptName)
End If
End Sub
Private Shared Function TryValidateEntity(oEntity As Act.Framework.MutableEntities.MutableEntity, lEntityType As ActGlobal.ActRegion, sFieldName As String, oFlagPic As System.Windows.Forms.PictureBox)As Boolean
Dim oField As Act.Framework.MutableEntities.MutableEntityFieldDescriptor
Dim oToolTip As System.Windows.Forms.ToolTip
Dim oViewForm As System.Windows.Forms.Form
Dim oPanel As System.Windows.Forms.Panel
Dim bTry As Boolean = False
If oFlagPic.Tag Is Nothing Then
oFlagPic.Tag = New System.Windows.Forms.ToolTip
Else
If TypeOf oFlagPic.Tag Is System.Windows.Forms.ToolTip Then
CType(oFlagPic.Tag, System.Windows.Forms.ToolTip).RemoveAll
oFlagPic.Tag = Nothing
End If
End If
' CurrentView ist ViewForm
oViewForm = m_oACTApp.CurrentView
' Feld ermitteln
oField = m_oAutodata.GetMutableEntityFieldDescriptor(lEntityType, sFieldName)
If oField Is Nothing Then
m_oError.SetError("Das Feld '{0}' wurde nicht im Bereich '{1}' gefunden.", sFieldName, lEntityType)
GoTo Abbruch
End If
Dim oValue As Object
' Feldwert von der aktuellen Entität ermitteln
oValue = oField.GetValue(oEntity)
If oValue Is Nothing Then
oFlagPic.Image = Melville_Schellmann.ACTOptimum6.Plugin.Icons.ResIcons.object_bell.ToBitmap
m_oBlinkTimer = New BlinkTimer(6, oFlagPic, "Achtung!", "Dieser Kontakt hat noch keine Anfrage zum Erhalt von Newslettern bekommen!", oViewForm)
m_oBlinkTimer.Enabled = True
Else
Select Case oValue.ToString.ToLower
Case "zustimmung angefragt"
oFlagPic.Image = Melville_Schellmann.ACTOptimum6.Plugin.Icons.ResIcons.flag_yellow.ToBitmap
m_oBlinkTimer = New BlinkTimer(0, oFlagPic, "Zustimmung wurde angefragt", "Eine Antwort steht noch aus.", oViewForm)
m_oBlinkTimer.Enabled = True
Case "zustimmung abgelehnt"
oFlagPic.Image = Melville_Schellmann.ACTOptimum6.Plugin.Icons.ResIcons.flag_red.ToBitmap
m_oBlinkTimer = New BlinkTimer(6, oFlagPic, "Achtung!", "Kunde hat den Erhalt von Newslettern abgelehnt!", oViewForm)
m_oBlinkTimer.Enabled = True
Case "zustimmung erteilt"
oFlagPic.Image = Melville_Schellmann.ACTOptimum6.Plugin.Icons.ResIcons.flag_green.ToBitmap
Case Else
oFlagPic.Image = Melville_Schellmann.ACTOptimum6.Plugin.Icons.ResIcons.object_bell.ToBitmap
m_oBlinkTimer = New BlinkTimer(6, oFlagPic, "Achtung!", "Dieser Kontakt hat noch keine Anfrage zu Erhalt von Newslettern bekommen!", oViewForm)
m_oBlinkTimer.Enabled = True
End Select
End If
oFlagPic.SizeMode = PictureBoxSizeMode.StretchImage
bTry = True
Abbruch:
Return bTry
End Function
Private Shared Function TryGetControl(oStartControl As system.Windows.Forms.Control, sControlName As String, typeControl As System.Type, ByRef oControl As system.Windows.Forms.Control) As Boolean
' Wenn Name und Klasse (bzw. Unterklasse) übereinstimmen, dann wurde COntrol gefunden.
If String.Compare(oStartControl.Name, sControlName, True) = 0 Then
If typeControl.Equals(oStartControl.GetType) OrElse oStartControl.GetType.IsSubclassOf(typeControl) Then
oControl = oStartControl
'MsgBox(oControl.GetType.ToString & " " & oStartControl.Name & " " & oStartControl.GetType.IsSubclassOf(typeControl))
Return True
End If
End If
Dim i As Integer
If oStartControl.Controls Is Nothing Then
Return False
End If
For i = 0 To oStartControl.Controls.Count - 1
If TryGetControl(oStartControl.Controls(i), sControlName, typeControl, oControl) = True Then
Return True
End If
Next
Return False
End Function
Private Shared Function TryGetCurrentEntityAndEntityType(ByRef oCurrentEntity As Act.Framework.MutableEntities.MutableEntity, ByRef lCurrentEntityType As ActGlobal.ActRegion) As Boolean
Dim bTry As Boolean = False
Select Case True
Case TypeOf m_oACTApp.CurrentView Is Act.UI.IContactDetailView
oCurrentEntity = m_oACTApp.ApplicationState.CurrentContact
lCurrentEntityType = ActGlobal.ActRegion.Contact
Case TypeOf m_oACTApp.CurrentView Is Act.UI.ICompanyDetailView
oCurrentEntity = m_oACTApp.ApplicationState.CurrentCompany
lCurrentEntityType = ActGlobal.ActRegion.Company
Case TypeOf m_oACTApp.CurrentView Is Act.UI.IGroupDetailView
oCurrentEntity = m_oACTApp.ApplicationState.CurrentGroup
lCurrentEntityType = ActGlobal.ActRegion.Group
Case TypeOf m_oACTApp.CurrentView Is Act.UI.IOpportunityDetailView
oCurrentEntity = m_oACTApp.ApplicationState.CurrentOpportunity
lCurrentEntityType = ActGlobal.ActRegion.Opportunity
Case Else
'm_oError.SetError("Die Ansicht '{0}' wird nicht unterstützt.", m_oACTApp.CurrentView.InterfaceDisplayName)
GoTo Abbruch
End Select
' Wenn es keine aktuelle Entität gibt dann abbrechen
If oCurrentEntity Is Nothing Then
m_oError.SetError("In der Ansicht '{0}' konnte keine aktuelle Entität ermittelt werden.", m_oACTApp.CurrentView.InterfaceDisplayName)
GoTo Abbruch
End If
bTry = True
Abbruch:
Return bTry
End Function
Private Shared Function IsVersionOrHigher(oCurrentVersion As system.Version, sMinumimVersion As String) As Boolean
Dim bIsVersionOrHigher As Boolean = False
Dim aPart() As String
Dim lNumber As Integer
aPart = sMinumimVersion.Split(New Char() {"."c}, StringSplitOptions.RemoveEmptyEntries)
Dim i As Integer
Dim bBuildNumbersAreEqual As Boolean
For i = 0 To aPart.Length - 1
If Integer.TryParse(aPart(i), lNumber) = False Then
m_oError.SetError("Es wurde eine falsche Versionsnummer '{0}' angegeben.", sMinumimVersion)
GoTo Abbruch
End If
Select Case i
Case 0
If oCurrentVersion.Major < lNumber Then
GoTo Abbruch
End If
Case 1
If oCurrentVersion.Minor < lNumber Then
GoTo Abbruch
End If
Case 2
If oCurrentVersion.Build < lNumber Then
GoTo Abbruch
End If
If oCurrentVersion.Build = lNumber Then
bBuildNumbersAreEqual = True
Else
bBuildNumbersAreEqual = False
End If
Case 3
If bBuildNumbersAreEqual And oCurrentVersion.Revision < lNumber Then
GoTo Abbruch
End If
Case Else
m_oError.SetError("Es wurde eine falsche Versionsnummer '{0}' angegeben.", sMinumimVersion)
GoTo Abbruch
End Select
Next
'm_oAutodata.ShowObject(m_oAutodata.ACTOptimum.ProductVersion)
bIsVersionOrHigher = True
Abbruch:
Return bIsVersionOrHigher
End Function
Private Shared Sub PrintError(sMessage As String, sTitle As String)
ActGlobal.WriteToACTEventLog(sTitle, EventLogEntryType.Error, sMessage)
End Sub
Private Class BlinkTimer
Inherits Timer
Private m_oPic As System.Windows.Forms.PictureBox
Private m_oStartImage As system.Drawing.Image
Private m_oToolTip As System.Windows.Forms.ToolTip
Private m_sTitle As String
Private m_sMessage As String
Private m_oWindow As IWin32Window
Private m_lStartCount As Integer
Private m_lCount As Integer
Public Sub New
MyBase.New
m_oPic = Nothing
m_sTitle = String.Empty
m_sMessage = String.Empty
m_lStartCount = 0
m_lCount = 0
End Sub
Public Sub New(lCount As Integer, oPic As System.Windows.Forms.PictureBox, sTitle As String, sMessage As String, oWindow As IWin32Window)
Me.New
m_oPic = oPic
m_oStartImage = oPic.Image
m_lStartCount = Math.Min(Math.Max(1, lCount), 12)
m_lCount = m_lStartCount
Me.Interval = 200
m_sMessage = sMessage
m_sTitle = sTitle
m_oWindow = oWindow
AddHandler Me.Tick, AddressOf onTimerTick
End Sub
Private Sub onTimerTick(sender As Object, e As EventArgs)
Me.Enabled = False
m_lCount = m_lCount - 1
If m_lCount Mod 2 = 0 Then
m_oPic.Image = m_oStartImage
Else
m_oStartImage = m_oPic.Image
m_oPic.Image = Nothing
End If
If m_lCount <= 0 Then
If Not String.IsNullOrEmpty(m_sMessage) Then
m_oToolTip = New System.Windows.Forms.ToolTip
m_oToolTip.ToolTipTitle = m_sTitle
m_oToolTip.Show(m_sMessage, m_oWindow, m_oPic.Location + m_oPic.Parent.Location + New System.Drawing.Point(m_oPic.Width + 4, 0), 2000)
m_oPic.Tag = m_oToolTip
m_oToolTip.SetToolTip(m_oPic, m_sMessage)
End If
GoTo Abbruch
End If
Me.Enabled = True
Abbruch:
End Sub
End Class
Private Sub Dummy()