Wie gestaltet man einen Join am sinnvollsten für VBA?
Gewünschter Join-Ausdruck:
- Code: Alles auswählen
From (Tab1 Left Join Tab2 ON (Tab1.F1 = Tab2.F2 AND 5 < Tab2.F3)) Left Join Tab3 on Tab1.F1 = Tab3.F2
Vorschlag:
- Code: Alles auswählen
Generator.LeftJoin("Tab1", "Tab2", "F1", RelationalOperators_Equal, "F2", 5, RelationalOperators_LessThan, "F3") _
.LeftJoin("Tab1", "Tab3", "F1", RelationalOperators.Equal, "F2").ToString
Problem:
Gewünschter Join-Ausdruck:
- Code: Alles auswählen
From (Tab1 Left Join Tab2 ON (Tab1.F1 = Tab2.F2 AND "a" < Tab2.F3)) Left Join Tab3 on Tab1.F1 = Tab3.F2
=>
- Code: Alles auswählen
Generator.LeftJoin("Tab1", "Tab2", "F1", RelationalOperators_Equal, "F2", "a", RelationalOperators_LessThan, "F3") _
.LeftJoin("Tab1", "Tab3", "F1", RelationalOperators.Equal, "F2").ToString
.. wie weiß man nun, das "a" ein String und kein Feldname ist?
Lösungsansatz:
=> Für so einen Fall den Umweg über den ConditionGenerator gehen und folgendes verwenden:
- Code: Alles auswählen
set field1 = FieldGenerator.Field("F1", "Tab1")
set field2 = FieldGenerator.Field("F2", "Tab2")
set field3 = FieldGenerator.Field("F3", "Tab2")
set condition = ConditionGenerator.Add(field1, RelationalOperators_Equal, field2).Add("a", RelationalOperators_LessThan, field3)
Generator.LeftJoinCondition("Tab1", "Tab2", condition) _
.LeftJoin("Tab1", "Tab3", "F1", RelationalOperators.Equal, "F2").ToString
Dann könnte man aber vielleicht gleich alle umständlicheren Vergleiche auslagern und bei LeftJoin nur noch Equal voraussetzen. =>
- Code: Alles auswählen
set field1 = FieldGenerator.Field("F1", "Tab1")
set field2 = FieldGenerator.Field("F2", "Tab2")
set field3 = FieldGenerator.Field("F3", "Tab2")
set condition = ConditionGenerator.Add(field1, RelationalOperators_Equal, field2).Add("a", RelationalOperators_LessThan, field3)
Generator.LeftJoinCondition("Tab1", "Tab2", condition) _
.LeftJoin("Tab1", "Tab3", "F1", "F2").ToString
... oder wir nutzen eine festgelegte Sprache um eine Bedingung als String zu formatieren, zerlegen diesen String in seine Bestandteile und bauen daraus im Net-Code eine ICondition auf.
=>
- Code: Alles auswählen
Generator.LeftJoin("Tab1", "Tab2", "F1 = F2", "'a' < F3") _
.LeftJoin("Tab1", "Tab3", "F1 = F2").ToString
=> F1 wird dann zu Tab1.F1, weil es links vom Vergleichszeichen steht. Alles was rechts steht erhält als Source den Eitnrag aus dem rechten Source (2. Parameter).
Ein String wird durch '' gekennzeichnet. Ein String ohne ''-Markierung muss dann ein Feldname sein.
Nachteil (ein großer nach meinem Geschmack) dieser Variante: die Feldnamen können nur noch per String übergeben werden. Hätte ich die Felder sowieso als IField verfügbar, muss ich das im VBA-Code wieder zu einem String machen.
Weitere Ansatz:
Wir pfeiffen auf die ISqlGenerator-Rückgabe der Join-Methoden und erlauben dahinter eine Condion zu erzeugen.
- Code: Alles auswählen
set field1 = FieldGenerator.Field("F1", "Tab1")
set field2 = FieldGenerator.Field("F2", "Tab2")
set field3 = FieldGenerator.Field("F3", "Tab2")
with Generator
.LeftJoin("Tab1", "Tab2").Condition(field1, RelationalOperators_Equal, field2).Add("a", RelationalOperators_LessThan, field3)
.LeftJoin("Tab1", "Tab3").Condition(field1, RelationalOperators_Equal, field3)
sql = .ToString
end with
mfg
Josef