JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.Hallo zusammen,
Zurück mit einer weiteren Frage zur JSL-Programmierung. Es hängt mit den anderen Beiträgen zusammen, z Hier .
Ich hätte gerne eine Check Box()-Funktionalität, die, wenn das Kontrollkästchen aktiviert ist (Status=1), die ausgewählten Zeilen (es handelt sich zufällig um Zeilen, bei denen RSquare negativ ist) ausgewählt und dann ausgeblendet und entfernt wird, damit der Graph Builder aktualisiert wird zeigt die gewünschte Ausgabe an. Wenn das Kontrollkästchen dann deaktiviert ist (Status=0), werden diese Zeilen eingeblendet und der Ausschluss aufgehoben. Der Set Function()-Aufruf, den ich verwende, ist unten aufgeführt. Er funktioniert, wenn ich das „Skript“ von Set Function() manuell ausführe, dies geschieht jedoch nicht automatisch. Ich kann nicht herausfinden, was mir fehlt, damit es automatisch aktualisiert wird. Ich habe einen netten Beitrag gefunden Hier , und ich versuche es zu tun etwas Wie das, was diese Person getan hat, aber für die Aktualisierung des Graph Builder.
JSL-Set-Funktionsaufruf:
cb << Set Function(<BR />{this},<BR />this = cb << Get;<BR />If(<BR />this == 1,<BR />dt_results << Select Rows( neg_rows ) << Hide and Exclude;<BR />dt_results << Clear Select;<BR />dt_tb = dt_results << Get As Report();,<BR />this == 0,<BR />dt_results << Select Rows( neg_rows ) << Unhide;<BR />dt_results << Select Rows( neg_rows ) << Unexclude;<BR />dt_results << Clear Select;<BR />dt_tb = dt_results << Get As Report()<BR />);<BR />);cb << Set Function(
{this},
this = cb << Get;
If(
this == 1,
dt_results << Select Rows( neg_rows ) << Hide and Exclude;
dt_results << Clear Select;,
this == 0,
dt_results << Select Rows( neg_rows ) << Unhide;
dt_results << Select Rows( neg_rows ) << Unexclude;
dt_results << Clear Select;
);
);Dabei wird cb weiter oben im Code wie folgt bezeichnet:
cb = Check Box( "Remove bad points (*'s)?", <<SET></SET>
Ausgabe starten oder immer dann, wenn das Kontrollkästchen den Status = 0 hat:

Gewünschte Ausgabe, wenn das Kontrollkästchen den Status = 1 hat:

Es wäre schön, die Datentabelle auch als Bericht auf der rechten Seite zu aktualisieren, sodass alle ausgeschlossenen Zeilen dann aus der Berichtsansicht auf der rechten Seite entfernt würden, aber ich denke, das könnte viel schwieriger sein, als es sich anhört. Ich habe versucht, ein zusätzliches „Get As Report“-Update im Befehl „Set Function()“ hinzuzufügen, aber es führt nichts aus.
Wir freuen uns über jedes Feedback, danke!,
DS
Datenmischung und -bereinigungBetreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.In meiner täglichen Arbeit stoße ich eher auf das gegenteilige Problem:
Nicht: 2 Fenster, die denselben Namespace teilen
aber: 2 Skripte, die nur manchmal *) ein gemeinsames haben Hier Namensraum.
Wenn ich eine JSL-Datei in eine andere einfüge, zur Laufzeit , das enthaltene Skript teilt die Hier Namespace der Haupt-JSL-Datei.
Aber wenn ich einige Codezeilen debuggen und sie vom zweiten Skript aus ausführen möchte, wie kann ich das einschließen? script_B Zugang zum Hier Namensraum des Hauptskripts? Als ich vor 2 Sekunden den Code von script_B ausgeführt habe, hatte er einfach Zugriff auf diesen Namespace.
https://community.jmp.com/t5/Discussions/Debugging-Jmp-applications/mp/701121/highlight/true#M88566
Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax von Set Function()Danke, @ErraticAttack, für das schöne Beispiel, wie Scoping in Jmp funktioniert.
Es hat mir sehr geholfen, dem Verständnis näher zu kommen ...
Bisher konnte ich nicht verstehen, was @drewfoglia meinte mit

in Grundlegendes Scripting für Effizienz und Reproduzierbarkeit: Weniger tun, um mehr zu erreichen (2019-US-TUT-290)
Ihr Beispiel zeigt schön, dass das nicht stimmt.
Warum unterscheidet sich unsere Erfahrung hier von Drews Aussage?
Ich denke, das liegt daran, dass die Fenster aus demselben JSL-Editorfenster erstellt werden.
Nach dem Öffnen des ersten TEST-Fensters ist es sehr hilfreich, dass das Skriptfenster weiterhin Zugriff auf die referenzierten Objekte teb und tb hat.
Nach dem Öffnen des zweiten TEST-Fensters verweisen teb und tb nun auf die Objekte im zweiten Fenster - was anscheinend die Funktionalität des ersten Fensters beeinträchtigt (der eingegebene Text wird in tb , also im zweiten Fenster, angezeigt).
Wenn wir also beide Ansprüche verknüpfen, stellt sich die Frage, was passiert, wenn beide Windows-Betriebssysteme keinen gemeinsamen JSL-Editor verwenden.
-> Beide werden einen unabhängigen NameSpace haben, wie Drew in seinem Vortrag angekündigt hat.
Möglichkeiten hierzu:
a) Schließen Sie das Skript und öffnen Sie es erneut. Anschließend erstellen Sie das zweite Fenster.
b) Rufen Sie das Skript aus einem Menü auf:

Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.Hallo @ErraticAttack ,
Vielen Dank für Ihre Antwort und Ihren ausführlichen Beitrag. Es wird sicherlich einige Zeit dauern, bis ich es durchgearbeitet habe, da ich kein professioneller Programmierer bin und vieles davon noch neu für mich ist.
Danke!,
DS
Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.@ich h Als Beispiel dafür, dass JMP den Bereich nicht so festlegt, wie man es erwarten würde (besonders wenn es beispielsweise von Python kommt), starten Sie einfach zwei Fenster aus diesem Skript – die Namen verweisen nur auf das zweite Fenster, nicht auf das erste.Dies ist das größte Problem, das die Leute bei der Festlegung des Umfangs haben (aber nicht das einzige Problem).JMP bietet einige praktische Pseudo-Namespaces, wie zum Beispiel den Namespace window:.Dies sind jedoch keine richtigen Namespace-Variablen und funktionieren in großen Skripten nicht vollständig wie erwartet.
Names Default to Here( 1 );
New Window( "TEST",
V List box(
teb = Text Edit Box( "", <<SET hint=""></SET>
@SDF1 Für das explizite Namespace-Scoping habe ich eine Bibliothek erstellt, die alle mühsamen Scope-Injection-Aufgaben über Metaprogrammierung erledigt.Dies hat den zusätzlichen Vorteil, dass Klassen fast genau so definiert werden können, wie sie in Python funktionieren (abzüglich der praktischen Suchüberschreibungen).Ich kann die Bibliothek nicht teilen, da sie Teil meiner Unternehmensarbeit ist, aber im Wesentlichen geschieht Folgendes:
Angenommen, Sie haben ein einfaches Skript wie dieses
Names Default to Here( 1 );
/*
Doing something initialization here!!
*/
dt = Current Data Table();
New Window( "Super Useful Script",
,
<<ON close=""></ON>
Dieses Skript verfügt über zwei interaktive UI-Elemente, eine Initialisierung und möglicherweise eine Bereinigung beim Schließen des Fensters.Beachten Sie, dass der Anzeigebaum und die Logik konzeptionell vermischt sind und es sehr tiefe Blöcke gibt.Code sieht besser aus (und ist einfacher zu warten), wenn auch konzeptionell unterschiedliche Elemente im Code unterschiedlich sind.Es wäre schön, einfach eine Schaltflächenbox mit einem Titel und einem aufzurufenden Funktionsnamen zu erstellen.Die aufgerufene Funktion ist dann eine Funktion der obersten Ebene (die von jedem Teil des Skripts problemlos anderweitig aufgerufen werden kann) und vom Anzeigebaum getrennt.
Sie können dies in etwas umwandeln, das _viel_ einfacher zu verdauen ist und mit dem Sie arbeiten können, das wie folgt aussieht:
/* super useful script */
initialize = Function( {}, // entry point to script
/* perform any initialization needed here */
self:dt = Current Data Table();
1
);
content = Function( {}, // this holds the display tree
V List Box(
self:one click button = meta:Button Box( "Useful 1-click function", "call one click" )
,
H List Box(
self:value teb = meta:Text Edit Box( "", "handle value change" ) << Set Hint( "Enter Value" )
)
)
);
finalize = Function( {}, // called after display tree has finalized
1
);
on close = Function( {}, // called when window wants to close
1
);
call one click = Function( {}, // called when button is pressed (line 11)
Print( "Done" )
);
handle value change = Function( {}, // called when TEB value changes(line 14)
Print( "Doing something special" )
);Nun ist klar, dass dieses Skript nicht viel bewirken wird, wenn Sie die normale JSL-Schaltfläche zum Ausführen des Skripts drücken.Dazu müssen Sie zunächst den Meta-Namespace definieren (der den ButtonBox- und den TextBox-Wrapper enthält, damit sie sich gut mit dem Rest des Skripts verknüpfen lassen) und eine Meta-Programmier-Wrapper-Funktion definieren, die Folgendes tut:
Nehmen Sie ein Prototyp-Skript wie dieses
<SOME script="" is="" above="" me="">
do someting = Function( {},
...
);
finalize = Function( {},
...
);
<MORE script="" is="" below="" me=""></MORE></SOME>Wandeln Sie es in diesen Prototyp um:
<SOME script="" is="" above="" me="">
self:do someting = Function( {},
self = Namespace( "#434" );
...
);
self:finalize = Function( {},
self = Namespace( "#434" );
...
);
<MORE script="" is="" below="" me=""></MORE></SOME>
Diese Metaprogrammierungsfunktion definiert „self“ einfach als „self = New Namespace()“ und fügt dann die self-Definition wie oben in jede Funktion ein (das „#434“ wird natürlich jedes Mal anders sein).Nachdem das Skript neu geschrieben wurde, gehen Sie einfach wie folgt vor (dies ist fast genau aus meiner Bibliothek übernommen)
If( self << Contains( "initialize" ), Try( self:initialize(), Print( "Error with self:initialize" ); Show( exception_msg ); ); );
Eval(
Substitute(
Expr(
self:window = New Window( self:tool name,
<<ON close="">>" ) );
Try(
self:finalize
,
Print( "Error with self:finalize" );
Show( exception_msg );
);</ON>
Hier ist ein tatsächliches Beispiel, das ich in meinem Skript habe.Die Eingabe vor der Metaprogrammierung ist folgende:
tool name = "Example";
initialize = Function( {},
{Default Local},
Show( "initialized" )
);
content = Function( {},
H List Box(
meta:Button Box( "Hello World", "run" )
,
self:n days box = meta:Number Edit Box( 30, "run" )
)
);
run = Function( {},
{var1, var2},
Show( "running" )
);
finalize = Function( {},
Show( "finalized" );
show( self:n days box << Get );
);
0;Kurz vor der Auswertung des Skripts (nach dem Metaprogrammierungsschritt) sieht es so aus
self:tool name = "Example";
self:initialize = Function( {},
{Default Local},
self = Namespace( "#58" );
Show( "initialized" );
);
self:content = Function( {},
{self, this},
self = Namespace( "#58" );
H List Box(
meta:Button Box( "Hello World", "run" )
,
self:n days box = meta:Number Edit Box( 30, "run" )
);
);
self:run = Function( {},
{var1, var2, self, this},
self = Namespace( "#58" );
Show( "running" );
);
self:finalize = Function( {},
{self, this},
self = Namespace( "#58" );
Show( "finalized" );
Show( self:n days box << Get );
);
0;Um es noch einmal zusammenzufassen: Die Metaprogrammierung erfordert alles uskopiert Variable der obersten Ebene und beschränkt sie explizit auf „self“.Dann nimmt es eine beliebige Funktion der obersten Ebene und fügt eine erste Zeile hinzu (die „self = Namespace( )“ ist).Das ist konzeptionell ziemlich einfach und es stellt sich heraus, dass es mit JSL ziemlich einfach zu implementieren ist.Leider gibt es je nach Form der Funktion „Function()“ mehrere Zweige (ob es sich um 2 oder 3 Argumente handelt, ob das 2. Argument {Default Local} ist oder einfach eine Liste lokaler Variablen).
Was bringt Ihnen also all diese Metaprogrammierung?Einfach um zu vermeiden, etwas Ähnliches zu tun, wie unten.Beachten Sie, dass das folgende Skript größtenteils in die Eval( Eval Expr( ... ) )-Anweisungen eingeschlossen ist.Dies verhindert, dass Sie solche Anweisungen in einer der Funktionen verwenden können und ist daher nicht ideal für große Projekte.Außerdem hat der Anzeigebaum immer noch einige hässliche Muster (der Block < ) ... ) ) ist groß und hässlich)
self = New Namespace();
self:tool name = "Example";
Eval( Eval Expr(
self:initialize = Function( {},
{Default Local},
self = Namespace( Expr( self << Get Name ) );
Show( "initialized" )
);
self:content = Function( {},
self = Namespace( Expr( self << Get Name ) );
H List Box(
Button Box( "Hello World",
<<SET function="">>" ) );
Try(
self:finalize
,
Print( "Error with self:finalize" );
Show( exception_msg );
);</SET>Dieses Skript enthält viele Musterbausteine, ist jedoch erforderlich, wenn Sie eine explizitere Bereichskontrolle wünschen.Insbesondere, wenn Sie Benutzern nicht sagen möchten: „Öffnen Sie jeweils nur ein Fenster!“.Das Erstellen des Metaprogrammierungsschritts ist etwas mühsam und erfordert auf jeden Fall viel Lernaufwand, aber sobald Sie es herausgefunden haben, ist es das auch sehr ist lohnend und ermöglicht auch viel prägnanteren und wartbareren Code.
Was ich hier überhaupt gezeigt habe, ist die Möglichkeit, Klassen zu erstellen (völlig getrennt von JMP14+ NewObject-Klassen), die sehr, sehr gut funktionieren und eine interaktive UI-Generierung zu einem Kinderspiel machen.
Ich weiß, dass das eine Menge ist (und vor allem weit entfernt von einem anfänglichen Ansatz zum Erstellen eines UI-Skripts), aber wenn Sie mehr als ein oder zwei kleinere UI-Skripte erstellen, kostet die Erstellung der Metaprogrammierung viel Zeit Wrapper (was Sie nur einmal tun müssen) wird sich schnell lohnen.
Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.Hallo @ErraticAttack ,
Vielen Dank für Ihr Feedback. Mir ist aufgefallen, dass Sie mir den Namespace() bereits zum zweiten Mal empfohlen haben ;-).
Aus diesem Grund habe ich die letzten anderthalb Tage damit verbracht, mich in meinem Scripting-Handbuch über die Verwendung von NameSpace zu informieren, das besser ist als der Scripting Index, aber immer noch nicht wirklich die besten Beispiele wie die Verwendung von NameSpace enthält.Haben Sie eine bessere Einführung als das JMP 14 Scripting Guide oder den Scripting Index zur Verwendung von Namespace im Kontext Ihrer Verwendung?
Ich muss zugeben, dass ich nicht ganz verstehe, was Sie tun, und es besser lernen muss. Basierend auf Ihrem Beitrag hier und dem Beispielcode, den Sie in einem meiner anderen Beiträge bereitgestellt haben Hier konnte ich meinen Skriptabschnitt, der das erste Fenster aufruft, mithilfe von Namespace() neu schreiben. Aber ich bin immer noch nicht ganz sicher, wie ich die folgenden Fenster und Anzeigen per Skript einbinden soll, da ich mit meinen nicht ganz so großen Skriptfähigkeiten in der Lage bin, damit zu arbeiten. Ich denke, es wird einige Zeit dauern, bis ich gelernt habe, wie man Namespace richtig verwendet, bevor ich zu dieser programmatischen Methode wechseln kann, was ich gerne tun würde.
Ich konnte den Graph Builder der Anzeige aktualisieren lassen, wenn ich das Kästchen zum Ausblenden/Ausschließen der negativen (in diesem Fall bedeutungslosen) Kontrollkästchen aktiviert/deaktiviert habe. Das folgende Skript macht das, was ich will (außer der Aktualisierung des Tabellenfelds, wenn bestimmte Daten aus dem Diagramm entfernt werden), aber ich verstehe, dass es vom Standpunkt der Programmierung aus nicht ideal ist.
Danke!,
DS
Names Default To Here( 1 );
lbWidth = 168;
dt = Open( "$SAMPLE_DATA/Boston Housing.jmp" );
// Expression to store the current settings in global variables
recallRolesS1 = Expr(
::dtchosenRecall = dtchosen
);
// Expression to clear all current settings. KW: Clear
clearRoles = Expr(
Try(
colListY << RemoveAll;
ColListX << RemoveAll;
ColListW << RemoveAll;
ColListF << RemoveAll;
colListV << RemoveAll;
)
);
// Expression to store the current settings in global variables
recallRoles = Expr(
::ycolRecall = colListY << GetItems;
::xcolRecall = colListX << GetItems;
::WcolRecall = colListW << GetItems;
::FcolRecall = colListF << GetItems;
::vcolRecall = colListV << GetItems;
::max_spRecall = max_sp_input << get;
::partVPRecall = partVP_input << Get;
);
//Function to choose the data table to model. KW: choose_data
choose_data_table = Function( {},
list = {};
For( i = 1, i <= N Table(), i++,
list[i] = Data Table( i ) << get name
);
win = New Window( "Select a data table",
<<MODAL> Training R².",
<<SET font="" size=""> 1, Throw( "Too many items selected!\!rOnly one selection possible." ),
N Items( SelRows ) == 1,
SelRows = this << Get Selected Rows;
NPCs = SelRows[1];
);
dt_results << Clear Select;
dt_results << Select rows( SelRows );
)
);
);
Part = Expr(
If(
N Items( vcols ) == 1,
dt_results = New Table( "Partition_Results",
Add Rows( max_sp ),
New Column( "Splits", Numeric, Continuous ),
New Column( "Training RSquare", Numeric, Continuous ),
New Column( "Validation RSquare", Numeric, Continuous ),
New Column( "Training RASE", Numeric, Continuous ),
New Column( "Validation RASE", Numeric, Continuous ),
New Column( "RSquare Diff", Numeric, Continuous, Formula( "Training RSquare"n - "Validation RSquare"n ) ),
New Column( "Penalized Valid RSquare", Numeric, Continuous, Formula( "Training RSquare"n - 0.05 * "Splits"n ) ),
New Column( "Training N", Numeric, Continuous ),
New Column( "Validation N", Numeric, Continuous )
),
N Items( vcols ) == 0 & Is Missing( partVP ) == 0,
dt_results = New Table( "Partition_Results",
Add Rows( max_sp ),
New Column( "Splits", Numeric, Continuous ),
New Column( "Training RSquare", Numeric, Continuous ),
New Column( "Validation RSquare", Numeric, Continuous ),
New Column( "Training RASE", Numeric, Continuous ),
New Column( "Validation RASE", Numeric, Continuous ),
New Column( "RSquare Diff", Numeric, Continuous, Formula( "Training RSquare"n - "Validation RSquare"n ) ),
New Column( "Penalized Valid RSquare", Numeric, Continuous, Formula( "Validation RSquare"n - 0.05 * "Splits"n ) ),
New Column( "Training N", Numeric, Continuous ),
New Column( "Validation N", Numeric, Continuous )
),
N Items( vcols ) == 0,
dt_results = New Table( "Partition_Results",
Add Rows( max_sp ),
New Column( "Splits", Numeric, Continuous ),
New Column( "Training RSquare", Numeric, Continuous ),
New Column( "Training RASE", Numeric, Continuous ),
New Column( "Penalized Train RSquare", Numeric, Continuous, Formula( "Training RSquare"n - 0.05 * "Splits"n ) ),
New Column( "Training N", Numeric, Continuous )
)
);
For( i = 1, i <= max_sp, i++,
dt_results:"Splits"n[i] = i
);
dt_name = dtchosen << Get Name;
For( i = 1, i <= N Rows( dt_results ), i++,
Psplit = dt_results:"Splits"n[i];
str = Eval Insert(
"report = (dtchosen<<PARTITION></PARTITION></SET></MODAL>Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.Hallo @ErraticAttack ,
Meiner Erfahrung nach ist die Festlegung des Variablenbereichs konsistent. Es ist vielleicht nicht intuitiv, aber ich habe es immer als vorhersehbar empfunden.Wenn Sie auf Inkonsistenzen stoßen, könnte es sich lohnen, in der Skriptanleitung nachzuschauen und zu versuchen, den Gültigkeitsbereich verschiedener Symbole zu überprüfen.
In einigen Situationen hatte ich großen Erfolg damit, die aufrufenden Kontextfunktionen zur Vereinfachung von Funktionsaufrufen zu verwenden, normalerweise für explorative Analysen oder Skripts, die interaktiv ausgeführt werden. Beispielsweise könnte eine Protokollfunktion Nachrichten an eine Datei oder ein Fenster senden und Iterator- oder Schrittwerte einschließen, ohne dass diese jedes Mal eingegeben/kopiert/eingefügt werden müssen.
Names default to here(1);
lg = function({msg},
write(msg || try(", i=" || char(i), "") || "\!N")
);
lg("starting loop");
local({i},for(i=1, i<= 5, i++, lg("done")))Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.Hallo @pmroz ,
Danke für die Rückmeldung. Ich wollte nur das aktuelle Fenster aktualisieren und kein neues erstellen. Ich konnte die Dinge für das Diagramm zum Laufen bringen, sodass es beim Aktivieren/Deaktivieren des Status des Kontrollkästchens() aktualisiert wird. Leider kann ich das Tabellenfeld, das die Datentabelle als Bericht enthält, immer noch nicht wie gewünscht aktualisieren. Dieser Teil stellt sich als viel komplizierter heraus, als ich gedacht hätte, aber er ist wirklich nicht so wichtig. Besser ist es, wenn die grafische Anzeige wie erwartet funktioniert. Dennoch wäre es schön, wenn die Tabellenbox aktualisiert werden könnte.
Danke!,
DS
Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.Beachten Sie, dass Sie sich nicht darauf verlassen können, dass das JSL-Scope-Walking bei <
Meistens liegt es daran, dass JSL nicht über eine strenge Bereichskontrolle verfügt, wie dies beispielsweise bei Python der Fall wäre.Für jede Art von komplizierter interaktiver Benutzeroberfläche sollten Sie immer explizit alle Variablen festlegen, die über mehrere Rückrufe von Anzeigeelementen hinweg bestehen bleiben müssen.
Außerdem sollten Sie aus ästhetischen und praktischen Gründen des Codeformats immer Kommas auf der Ebene des umschließenden Zauns setzen, wie unten beschrieben.Dies ermöglicht ein sehr schnelles und einfaches visuelles Verständnis der Codeblöcke.Beachten Sie die einfache visuelle Anzeige, wo sich die verschiedenen Blöcke der IF-Anweisung befinden.
Als letzte Anmerkung: Sie sollten das Schließen Ihres UI-Fensters mit dem Löschen des Namespace verknüpfen, indem Sie die <
ns = <RELEVANT namespace="" with="" variables="" defined="" above="">
Eval( Eval Expr(
ns:cb << Set Function( {this},
ns = Namespace( Expr( ns << Get Name ) );
state = this << Get;
If(
state == 1,
ns:dt_results << Select Rows( ns:neg_rows ) << Hide and Exclude;
ns:dt_results << Clear Select;
,
state == 0,
ns:dt_results << Select Rows( ns:neg_rows ) << Unhide;
ns:dt_results << Select Rows( ns:neg_rows ) << Unexclude;
ns:dt_results << Clear Select;
);
);
) );</RELEVANT>Betreff: JSL-Hilfe: Hilfe zur Befehlssyntax „Set Function()“.Versuchen Sie etwas wie Folgendes:
nw = new window("Test",
one_cb = checkbox({"Turn On"},
one_value = one_cb << Get;
If (one_value,
dt_results << Select Rows( neg_rows ) << Hide and Exclude;
dt_results << Clear Select;
dt_tb = dt_results << Get As Report();
// else
,
dt_results << Select Rows( neg_rows ) << Unhide;
dt_results << Select Rows( neg_rows ) << Unexclude;
dt_results << Clear Select;
dt_tb = dt_results << Get As Report()
);
)
);