Mark Posted January 8, 2010 Posted January 8, 2010 Ik heb een script gemaakt die kan bepalen welke tab er geselecteerd is: Set Variable [ $LayoutObjects; Value:Substitute(LayoutObjectNames(Get(FileName); Get(LayoutName)); ["¶"; ""]; ["<>"; "¶"]) ] Loop Set Variable [ $X; Value:$X + 1 ] Set Variable [ $Object; Value:Substitute(MiddleValues($LayoutObjects; $X; 1); "¶"; "") ] Set Variable [ $IsActiveTab; Value:GetLayoutObjectAttribute($Object; "isFrontTabPanel") ] Exit Loop If [ IsEmpty($Object) = 1 or $IsActiveTab = 1 ] End Loop Set Variable [ $$ActiveTab; Value:$Object ] Het zou helemaal mooi zijn om dit script om te bouwen naar een Custom Function. Kan iemand mij opweg helpen? Ik neem aan dat er gebruik gemaakt moet worden van recursie. Alvast bedankt. Quote
0 andries Posted January 8, 2010 Posted January 8, 2010 bestaat zelfs al ! http://www.fmcustomfunctions.com/functions_display_record.php?functionId=217 Quote
0 Mark Posted January 8, 2010 Author Posted January 8, 2010 @Andries: Bedankt voor de link. Het gaat er mij om dat ik (en hopelijk jullie ook) begrijp en leer hoe je van een script een Custom Function kunt maken. Ik heb het volgende gedaan: Function Name: IsActiveTab Let([ $LayoutObjects = Substitute(LayoutObjectNames(Get(FileName); Get(LayoutName)); ["¶"; ""]; ["<>"; "¶"]); $X = $X + 1; $Object = Substitute(MiddleValues($LayoutObjects; $X; 1); "¶"; ""); $IsActiveTab = GetLayoutObjectAttribute($Object; "isFrontTabPanel")]; If(IsEmpty($Object) = 1 or $IsActiveTab = 1; $Object; IsActiveTab)) Dit werkt gedeeltelijk. Wat doe ik fout? Quote
0 Mark Posted January 21, 2010 Author Posted January 21, 2010 Is er helemaal niemand die mij een zetje in de goede richting kan geven? Quote
0 Ari Posted January 22, 2010 Posted January 22, 2010 In de laatste regel achteraan staat isActiveTab. Dit moet volgens mij een variabele zijn dus: $isActiveTab Quote
0 Ari Posted January 22, 2010 Posted January 22, 2010 En als je isempty gebruikt hoef je dat niet te valideren dus = 1 kun je daar weglaten Quote
0 Ari Posted January 22, 2010 Posted January 22, 2010 En in een Let functie benoem je de variabelen zonder $ teken. Je hebt dat nu door elkaar gebruikt Quote
0 Mark Posted January 22, 2010 Author Posted January 22, 2010 @Ari: Bedankt voor je reactie. In de laatste regel achteraan staat isActiveTab. Dit moet volgens mij een variabele zijn dus: $isActiveTab Dat is de funtie die ik als recursion aanroep indien de actieve tab nog niet gevonden is. En als je isempty gebruikt hoef je dat niet te valideren dus = 1 kun je daar weglaten IsEmpty geeft een 0 of 1 terug. Persoonlijk vind ik If x = 1 Then logischer ogen dan If x Then. Maar het mag/kan allebei. En in een Let functie benoem je de variabelen zonder $ teken. Je hebt dat nu door elkaar gebruikt De naam van een variabel in een Let functie mag zowel zonder $ als met $ of $$. Bijvoorbeeld: Name, $Name of $$Name. Quote
0 rmw Posted January 22, 2010 Posted January 22, 2010 .....Dit werkt gedeeltelijk. Wat doe ik fout? Hoe bedoel je dat? Wat werkt wel en wat niet? Of is het Wanneer werkt het wel en wanneer niet? Mijn eerste indruk is: waarom alle layoutobjecten aflopen? Je kan een custom functie ook een parameter meegeven en als dat de object naam is, krijg je gelijk terug of het de front tab is of niet. Hoe denk je deze functie te gaan gebruiken? rmw Quote
0 Mark Posted January 23, 2010 Author Posted January 23, 2010 Hallo R, "Dit werkt gedeeltelijk" is inderdaad een beetje vaag. Wat werkt wel: als ik een tab selecteer en de functie aanroep dan krijg ik netjes de naam van de geselecteerde tab terug. Wat werkt niet: als ik een andere tab selecteer dan krijg ik geen waarde terug. Ik heb een lay-out met links bovenin het scherm de knoppen Nieuw, Eigenschappen, Verwijderen, ect. Verder staan er op deze lay-out een aantal tabs. Op elke tab staat een portaal. Als ik een bepaalde tab selecteer en op Nieuw druk, dient er een nieuw record toegevoegd te worden in de bijbehorende portaal. Om te bepalen aan welke portaal een record toegevoegd dient te worden, moet ik weten welke tab er geselecteerd is. Ik kan natuurlijk mijn eerder genoemde script of de link van Ari gebruiken. Dat heb ik (nog) niet gedaan, omdat ik het gebruik van recursie in een Custom Function (beter) wil begrijpen. Zelf denk ik dat de Custom Function niet helemaal werkt omdat $X in een later stadium niet meer op 0 word gezet. Is mijn verhaal een beetje duidelijk? Heb jij een idee/tip? Alvast bedankt. Quote
0 rmw Posted January 23, 2010 Posted January 23, 2010 Heldere uitleg, dank. Dan de functie zelf. Volgens mij zit het probleem in het gebruik van lokale variabelen. Je variabelen in een Let() functie hoeven niet voorzien te zijn van het dollar-teken. FM zelf zegt over lokale variabelen: Lokale en algemene variabelen kunnen in berekeningen worden gemaakt en gebruikt. • Een lokale variabele kan alleen worden gebruikt in scriptstappen in het script dat wordt uitgevoerd. De waarde in een lokale variabele wordt gewist wanneer het script wordt afgesloten. Je gebruikt ze hier echter niet in een script, maar in een custom functie. Ik weet niet wanneer die worden opgeruimd. Daarnaast begrijp ik de substitute niet. Je wilt met de lijst van objectnames aan de slag, maar je vervangt de return bewust door niks. Die groter en kleiner dan tekens die blijkbaar terugkomen van een tab object zitten je verder niet in de weg. Dus niks aan doen. Tenslotte wil je de lijst met objectnames doorlopen, maar elke keer dat je de functie aanroept ga je die opnieuw uitlezen. Waarom geeft je de lijst niet mee als parameter aan de functie? Je kan dan tevens het aantal items dat je gevonden hebt meegeven als maximum. Voordeel is dan dat je binnen de functie gebruik maakt van informatie die niet meer wijzigt. Ik zou het zo opzetten: Functie: IsActiveTab ( theList ; theMax ) Let ( [ xObject = GetValue ( theList ; theMax ); xTab = GetLayoutObjectAttribute ( xObject ; "isFrontTabPanel" ) ] ; If ( theMax = 0 ; "" ; If ( xTab ; xObject ; IsActiveTab ( LeftValues ( theList ; theMax - 1 ) ; theMax - 1 ) ) ) ) In aanroep gebruik je dat dan als volgt: IsActiveTab ( LayoutObjectNames ( Get ( FileName ) ; Get ( LayoutName ) ) ; ValueCount ( LayoutObjectNames ( Get ( FileName ) ; Get ( LayoutName ) ) ) ) Doordat nu de functie elke keer wordt aangeroepen met een teller die 1 lager is dan de vorige, worden alle objectnamen afgelopen, totdat de actieve tab is gevonden. Is er geen actieve tab, dan stopt het geheel als de lijst is afgelopen. Ik hoop dat het helpt. rmw Quote
0 Mark Posted January 25, 2010 Author Posted January 25, 2010 Bedankt voor je hulp. Ik ga er mee aan de slag. Jouw functie maakt gebruik van twee parameters. Denk jij dat het ook te doen is zonder parameters? Quote
0 Mark Posted May 31, 2010 Author Posted May 31, 2010 (edited) Het is mij nog niet gelukt om het zonder parameters te doen. Hierbij mijn resultaat: Function Name: GetActiveTab Parameter: LayoutObjects Code: If(IsEmpty(LayoutObjects) = 0; Let([ Object = LeftValues(LayoutObjects; 1); ObjectsNext = RightValues(LayoutObjects; ValueCount(LayoutObjects) - 1)]; If(GetLayoutObjectAttribute(Left(Object; Length(Object) - 1); "isFrontTabPanel") = 1 and Left(Object; 3) = "Tab"; Object; GetActiveTab(ObjectsNext)) )) Je kunt de functie als volgt aanroepen: GetActiveTab(LayoutObjectNames(Get(FileName); Get(LayoutName))) De tabnamen (bij Object Info > Object Name) dienen te beginnen met: Tab Bijvoorbeeld: Tab1, Tab2, Tab3, etc. Edited June 1, 2010 by Guest Quote
0 andries Posted June 1, 2010 Posted June 1, 2010 Je gebruikt ze hier echter niet in een script, maar in een custom functie. Ik weet niet wanneer die worden opgeruimd. Lokale en globale variabelen kunnen in een let functie perfect gebruikt worden. Dit is soms gewenst als je bijvoorbeeld twee let functies in 1 calculatie gebruikt en bepaalde variabelen wil delen, of in sommige gevallen als je een evaluate wil gebruiken, dan is het soms beter om een lokale variabele te gebruiken. Zoals peter wagemans op FM Summit zei: niet elke variabele is gelijk . En er is een duidelijk verschil in de manier waarop FileMaker lokale en globale variabele enerzijds en de variabele die enkel leven binnen de let anderzijds behandeld. Lokale variabelen worden toegekend aan een script in een script stack. Als er geen script loopt wil dit zeggen dat ze worden toegevoegd aan de zogenaamde "empty script stack". Je kan dit testen door bijvoorbeeld volgende functie in je dataviewer te zetten: Let ( $test = "toto" ; "" ) en dan de waarde van $test opvragen in een andere entry van de data viewer. Je zal zien dat deze bestaat, ook al is ze niet zichtbaar in de "Current" tab. Dit is echter niet ondersteund door FileMaker, en kan ten allen tijde plotseling niet meer werken. Verder is het natuurlijk ook gevaarlijk om lokale variabelen in een let functie te gebruiken als deze functie ook wordt aangeroepen in het script, want dan overschrijft hij de waardes die eerder in het script aan die variabele waren toegekend. Als ik lokale variabelen gebruik in een let functie, met enkel het doel om ze binnen deze calculatie te gebruiken, dan check ik eerst of de variabele al niet bestaat, en sla dan de waarde op. Op het einde van mijn let functie, ken ik dan weer de originele waarde toe. Dit heeft als resultaat dat mijn script de waardes blijft behouden, of dat in de empty script stack de variabele na het aanroepen van de functie weer opgeruimd worden (ik ken namelijk een lege waarde toe aan de variabele). Quote
Question
Mark
Ik heb een script gemaakt die kan bepalen welke tab er geselecteerd is:
Het zou helemaal mooi zijn om dit script om te bouwen naar een Custom Function. Kan iemand mij opweg helpen?
Ik neem aan dat er gebruik gemaakt moet worden van recursie.
Alvast bedankt.
13 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.