Das Jahr 2017 steht kurz bevor und ich bin schon gespannt, was es mit sich bringt. Besonders gespannt bin ich natürlich auf die gemeinsame Zukunft von Automic und CA.

Während uns nichts anderes übrig bleibt, als abzuwarten, was auf uns zukommt, beherrscht die Automation Engine den Blick in die magische Kristallkugel. Damit kann sie uns ein paar Infos über die Zukunft geben.

In einem meiner letzten Blogartikel (So finden Sie übersprungene Jobs) habe ich schon über die Kalender in Automic geredet. Auch heute stehen die Kalender im Fokus. Ich will Ihnen zeigen, wie Sie mit der Automation Engine in die ferne Zukunft blicken können. Nicht mit Magie, dafür mit Kalendern und Calendar Keywords (=Kalenderbegriffe), bzw. „Calendar Events“, wie sie seit V12 heißen.

Dieser Blogartikel ist eine neue Auflage des alten Artikels „Forsight“, gemischt mit ein paar Infos aus einem anderen alten Artikel: „You see for(ward)“.

CALE ist kein Superfood

Cale ist gerade in aller Munde – sogar im wörtlichen Sinn. „Kale“ ist das englische Wort für Grünkohl, der gerade im Zuge der Superfood-Mode ungeahnte Beliebtheit gewinnt.

Für uns Automic User hat Cale dagegen eine ganz andere Bedeutung: Cale ist in der Automation Engine die übliche Abkürzung für Kalender. Kalender können in Automic für die zeitgesteuerte Aktivierung von Objekten verwendet werden. Die folgende Tabelle zeigt einige Objekttypen und die zugeordneten Calendar sowie Calendar Events:

Object Type Description DB Table(s) Field: Calendar Field: Keyword
JSCH Schedule-Tasks JPPC (EJPPC, AJPPC) JPPC_CALENAME JPPC_CALEKEYNAME
C_PERIOD Periodical Task EPDC (APDC) EPDC_CALENAME EPDC_CALEKEYNAME
EVNT Events OVP (EVP) OVP_CALENAME OVP_CALEKEYNAME

Funktionsweise von CALE

Ich habe es im oben erwähnten Artikel über übersprungene Jobs schon beschrieben: Die Automation Engine berechnet Kalender im Voraus. Wenn Sie ein neues Calendar Event anlegen und den Kalender speichern, kalkuliert die AE für eine bestimmte Anzahl an Jahren (in UC_CLIENT_SETTINGS eingestellt), wann das Calendar Keywort zutrifft.

Wenn Sie beispielsweise auf dem Mandat 1 ein Kalenderobjekt „CALE_GENERAL“ mit dem Calendar Event „MONDAYS“ haben, können Sie mit der folgenden Abfrage alle berechneten Tage für das Jahr 2017 ermitteln:

--select the calculated days from OKD
select OKD_Content from OKD
--the Calendar name is in OH, the Keyword name in OKB
inner join OH on OKD_OH_IDNR = OH_IDNR
inner join OKB on OKD_OH_IDNR = OKB_OH_IDNR and OKD_OKB_LNR = OKB_LNR
--filter the client, Calendar name, Keyword name and year
where OH_CLIENT = 1
and OH_NAME = 'CALE_GENERAL'
and OKB_NAME = 'MONDAYS'
and OKD_YEAR = 2017

Das Ergebnis dieser Abfrage ist der Inhalt des entsprechenden Feldes OKD_Content. Dieses Feld beinhaltet ein Bit-Array mit 372 Zeichen, also 31 Zeichen für jeden Monat. Jedes Zeichen steht für einen Tag und hat den Wert 1 oder den Wert 0, je nachdem, ob die Bedingung an dem Tag zutrifft oder nicht.

Damit die Grenze zwischen den Monaten leichter berechnet werden kann, werden für jeden Monat 31 Zeichen gespeichert. Der 1. März ist zum Beispiel immer an der 63. Stelle gespeichert, auch wenn wir ein Schaltjahr haben.

Im Jahr 2017 ist der 1. Januar ein Sonntag, der erste Montag im Jahr ist also der 2. Januar. Das Ergebnis der obigen Abfrage sieht also so aus:

01000000100000010000001000000100000010000001000000100000010000000001

Die grau markierten Nullen sind die nicht existierenden Tage 29, 30 und 31 im Monat Februar.

Kalenderbegriffe für einen Tag berechnen

Jetzt kommt endlich der angekündigte Blick in die Zukunft. Mit dem folgenden Script können Sie herausfinden, welche Calendar Events einen bestimmten Tag beinhalten. Im Beispiel suche ich nach Weihnachten 2018.

--MS SQL Server
--output the Client, the Calendar and the Keyword
select OH_Client as AE_Client, OH_Name as CALE_Name, OKB_Name as CALE_Keyword_Name
from OH inner join OKB on OH_Idnr = OKB_OH_Idnr
inner join OKD on OH_Idnr = OKD_OH_Idnr and OKB_Lnr = OKD_OKB_Lnr
where OH_DELETEFLAG = 0 and OH_REFIDNR = 0
--filter year 2018, month 12 and day 24
and OKD_Year = 2018
and SUBSTRING(OKD_Content,((12-1)*31+24),1) = 1  --T-SQL
--and SUBSTR(OKD_Content,((12-1)*31+24),1) = 1  --Oracle
--sorting
order by OH_Client, OH_Name, OKB_Name;

Anwendungsbeispiel: Was läuft in der Zukunft?

Das Script aus dem letzten Abschnitt können wir jetzt nutzen, um herauszufinden, welche aktiven JSCH-Tasks, EVNT und Periodencontainer an einem bestimmten Tag in der Zukunft laufen werden, also einen Kalenderbegriff verwenden, der den Tag enthält.

Die Abfrage enthält NUR Objekte mit Kalenderbedingung, sie gibt also keine komplette Liste mit Tasks zurück, die für den 24. Dezember 2018 eingeplant sind.

--MS SQL
--PART I
--Retrieve all relevant Calendars and Keywords as "CALEKEYS"
with CALEKEYS (CALEKEYS_Client, CALEKEYS_Calename, CALEKEYS_Keyname) as (
select OH_Client, OH_Name, OKB_Name
from OH inner join OKB on OH_Idnr = OKB_OH_Idnr
inner join OKD on OH_Idnr = OKD_OH_Idnr and OKB_Lnr = OKD_OKB_Lnr
where OH_DELETEFLAG = 0 and OH_REFIDNR = 0
--filter year 2018, month 12 and day 24
and OKD_Year = 2018
and SUBSTRING(OKD_Content,((12-1)*31+24),1) = 1  --T-SQL
--and SUBSTR(OKD_Content,((12-1)*31+24),1) = 1  --Oracle
)
--PART II
--Usage of Calendar Keywords in Schedule-Tasks
select 'JSCH' "Usage Type",
EH_Client "UC4 Client", EH_Name "Object Name", EJPP_OBJECT "Task Name",
CALEKEYS_Calename "Calendar Name", CALEKEYS_Keyname "Keyword Name"
from EH
inner join EJPP on EH_AH_Idnr = EJPP_AH_IDNR
inner join EJPPC on EH_AH_Idnr = EJPPC_AH_IDNR and EJPP_LNR = EJPPC_EJPP_LNR
inner join CALEKEYS on EH_Client = CALEKEYS_Client and EJPPC_CALENAME = CALEKEYS_Calename
and EJPPC_CALEKEYNAME = CALEKEYS_Keyname
--filter only tasks with "Active" flag on
where EJPP_ACTIVE = 1
--filter only "if one condition matches"
and EJPP_CCTYPE = 2
UNION
--PART III
--Usage of Calendar Keywords in Events
select 'EVNT' "Usage Type",
EH_Client "UC4 Client", EH_Name "Object Name", '-' "Task Name",
CALEKEYS_Calename "Calendar Name", CALEKEYS_Keyname "Keyword Name"
from EH
inner join EVP on EH_AH_Idnr = EVP_AH_IDNR
inner join CALEKEYS on EH_Client = CALEKEYS_Client and EVP_CALENAME = CALEKEYS_Calename
and EVP_CALEKEYNAME = CALEKEYS_Keyname
UNION
--PART IV
--Usage of Calendar Keywords in "Recurring Tasks" (C_PERIODs)
select 'C_PERIOD' "Usage Type",
EH_Client "UC4 Client", EH_Name "Object Name", '-' "Task Name",
CALEKEYS_Calename "Calendar Name", CALEKEYS_Keyname "Keyword Name"
from EH
inner join EPD on EH_AH_Idnr = EPD_AH_IDNR
inner join EPDC on EH_AH_Idnr = EPDC_AH_IDNR and EPD_LNR = EPDC_EPD_LNR
inner join CALEKEYS on EH_Client = CALEKEYS_Client and EPDC_CALENAME = CALEKEYS_Calename
and EPDC_CALEKEYNAME = CALEKEYS_Keyname
--filter only if Calendar is used and "if one condition matches"
and EPD_DaysMode = 'C'
and EPD_CALETYPE = 2
--PARTV
--Sorting
order by "UC4 Client", "Usage Type", "Object Name"

Ich wünsche ein schönes neues Jahr

Das vergangene Jahr war ziemlich spannend – und das kommende verspricht schon mindestens genauso aufregend zu werden.

Ich wünsche Ihnen ein tolles Jahr 2017!