Moravské přístroje, a. s., zdroj: https://www.mii.cz/art?id=653&lang=405, vytištěno: 01.11.2025 20:58:45
Hlavní stránka▹Podpora▹FAQ | 25.4.2022 |
|---|
|
Obsah sekce:
Univerzální MessageBoxPotřebujete zobrazovat různá hlášení za běhu aplikace, na které musí obsluha zareagovat? Příklad MessageBox ukazuje jak na to. Download: MessageBox.zip Tip na efektivní zálohování (backup) hodnotPříklad BackupOnChange.cw ukazuje jak automaticky aktivovat zálohování hodnot (backup) při změně hodnoty datového elementu. settings
...
backup
method = on_demand;
end_backup;
...
end_settings;
...
data
var X {backuped = true};
b1 : boolean;
b2 : boolean {backuped = false};
r1 : real;
r2 : real {backuped = false};
procedure OnScalarLogicalChange( var DataElement : boolean );
begin
(*
Procedura je vyvolána vždy, když dojde ke změne skalárního booleanovského datového elementu.
Backup() se volá jen pro datové elementy, které mají nastaven atribut backuped na true.
*)
if DataElement:backuped then
Backup();
end;
end_procedure;
procedure OnScalarNumericalChange( var DataElement : real );
begin
(*
Procedura je vyvolána vždy, když dojde ke změne skalárního numerického datového elementu.
Backup() se volá jen pro datové elementy, které mají nastaven atribut backuped na true.
*)
if DataElement:backuped then
Backup();
end;
end_procedure;
end_var;
end_data;
Poznámka: Pokud mají být zálohovány všechny datové elementy definované v datové sekci, není třeba testovat atribut backuped. Zápis procedury se zjednoduší jen na zavolání OCL procedury Backup(). procedure OnScalarNumericalChange( var DataElement : real ); begin Backup(); end_procedure; Download: BackupOnChange.cw Archivace změn hodnot (journal) pomocí datové sekce archivePříklad Journal.cw ukazuje možnost archivace změn hodnot (obdoba přístroje journal) pomocí datové sekce archive a událostních procedur datových sekcí. Výhodou tohoto řešení je možnost sdílet tyto události v distribuovaných aplikacích a jejich prohlížení pomocí přístroje data_viewer. Aplikace využíva uživatelských atributů user0 a user1, kde v atributu user0 je uložen text, popisující událost a atribut user1 slouží pro uchování původní hodnoty datového elementu. Pro vyhodnocení změn hodnot datových elementů jsou použity událostní procedury datových sekcí On*Change. archive Journal;
Message : string {comment = 'Message'};
NewValue : string {comment = 'New value'};
OldValue : string {comment = 'Old value'};
Operator : string {init_value = 'none'; comment = 'Operator'; user0 = 'User changed'};
DataElement : string {comment = 'Data element'};
procedure Notify( DE, Msg, OldVal, NewVal : string );
begin
DataElement = DE;
Message = Msg;
OldValue = OldVal;
NewValue = NewVal;
Archive();
end_procedure;
procedure On_Operator_Change();
begin
Notify( 'Operator', Operator:user0, Operator:user1, Operator:value_string );
Operator:user1 = Operator:value_string;
end_procedure;
end_archive;
var LogVars;
b : boolean {user0 = 'Boolean value changed'};
r : real {user0 = 'Real value changed'};
s : string {user0 = 'String value changed'};
procedure OnScalarLogicalChange( var DataElement : boolean );
begin
Journal.Notify( DataElement:long_name, DataElement:user0, DataElement:user1, DataElement:value_string );
DataElement:user1 = DataElement:value_string; (* Save current value to user1 atribute *)
end_procedure;
procedure OnScalarNumericalChange( var DataElement : real );
begin
Journal.Notify( DataElement:long_name, DataElement:user0, DataElement:user1, DataElement:value_string );
DataElement:user1 = DataElement:value_string; (* Save current value to user1 atribute *)
end_procedure;
procedure OnScalarStringChange( var DataElement : string );
begin
Journal.Notify( DataElement:long_name, DataElement:user0, DataElement:user1, DataElement:value_string );
DataElement:user1 = DataElement:value_string; (* Save current value to user1 atribute *)
end_procedure;
end_var;
Download: Journal.cw Proměnné časování přístrojePotřebujete-li u přístroje měnit periodu časování, můžete to vyřešit tak, že parametr period nastavíte na hodnotu infinite a přepíšete událostní proceduru OnActivate příslušného přístroje tak, jak je uvedeno v následujícím příkladu: var
Period : real {init_value = 1};
end_var;
procedure OnActivate();
begin
pause Period;
send self;
end_procedure;
Download: VariableTiming.cw Vícerozměrná poleControl Web umožňuje pracovat pouze s jednorozměrným polem. Pokud potřebujete vícerozměné pole, můžete se inspirovat následujícím příkladem, který ukazuje práci s dvourozměrným polem. var Array;
A1 : array[ 0..49 ] of real {comment = 'array [0..9][0..4] of real'; user0 = '9'; user1 = '4'};
A2 : array[ 0..39 ] of real {comment = 'array [0..19][0..1] of real'; user0 = '19'; user1 = '1'};
procedure idx( Array : array of real; x, y : integer ): cardinal;
var
i : cardinal;
lindex : integer;
SizeX : integer;
SizeY : integer;
begin
lindex = loindex(Array);
SizeX = val(Array[ loindex(Array)]:user0, 10);
SizeY = val(Array[ loindex(Array)]:user1, 10);
if (x >= 0) and (x <= SizeX) and (y >=0 ) and (y <= SizeY) then
return x + y * SizeX;
else
core.DebugOutput( 'ERROR: Index out of range. ' + Array[lindex]:name + '[' + x:s + ', ' + y:s + '] (' + Array[lindex]:name + ' : ' + Array[0]:comment + ')' );
core.StopApplication();
end;
end_procedure;
procedure GetItem( Array : array of real; x, y : cardinal ): real;
begin
return Array[ idx(Array, x, y ) ];
end_procedure;
procedure SetItem( Array : array of real; x, y : cardinal; Value : real );
begin
Array[ idx(Array, x, y ) ] = Value;
end_procedure;
end_var;
...
procedure xy();
var
r : real;
begin
Array.SetItem( Array.A1, 1, 2, 10 );
r = Array.GetItem( Array.A2, 9, 1, 10 );
end_procedure;
Jak automaticky odhlásit uživatele?Aplikace AutoLogout.cw ukazuje, jak lze vyřešit automatické odhlášení přihlášeného uživatele do aplikace v systému Control Web po definované době nečinnosti. Jak omezit počet vybraných položek v přístroji multi_switch v módu check_box.Jednoduchá aplikace demonstrující omezeni počtu vybraných položek v přístroji multi_switch v módu check_box. var
ba : array[ 1..5 ] of boolean;
end_var;
multi_switch switch_1;
const
maxSelected = 3;
end_const;
static
NoOfSelected : cardinal;
end_static;
owner = background;
position = 35, 35, 59, 77;
mode = check_box;
item
output = ba[1];
text = ' Item 1';
end_item;
item
output = ba[2];
text = ' Item 2';
end_item;
item
output = ba[3];
text = ' Item 3';
end_item;
item
output = ba[4];
text = ' Item 4';
end_item;
item
output = ba[5];
text = ' Item 5';
end_item;
procedure OnIndexOutput( Index : longint; Output : boolean );
begin
if Output <> ba[Index] then
if Output then
if NoOfSelected = maxSelected then
Output = false;
Update(false);
else
NoOfSelected = NoOfSelected + 1;
end; (* if *)
else
NoOfSelected = NoOfSelected - 1;
end; (* if *)
end; (* if *)
end_procedure;
end_multi_switch;
Download: CheckBoxRestriction.cw Jak měnit barvy pro jednotlivé stavy v přístroji multi_label.Pokud potřebujete zobrazovat texty a pozadí jednotlivých položek v přístroji multi_label různými barvami, můžete to udělat pomocí OCL procedur přístroje například takto: multi_label mlbl;
gui
owner = pSample;
position = 100, 40, 60, 20;
window
disable = zoom, maximize;
end_window;
end_gui;
justify = center;
item
expression = BoolArray[0];
text_list
font = font_caption;
text = 'Text 1';
end_text_list;
end_item;
item
expression = BoolArray[1];
text_list
font = font_caption;
text = 'Text 2';
end_text_list;
end_item;
item
expression = BoolArray[2];
text_list
font = font_caption;
text = 'Text 3';
end_text_list;
end_item;
item
expression = BoolArray[3];
text_list
font = font_caption;
text = 'Text 4';
end_text_list;
end_item;
procedure OnStartup();
begin
send self;
end_procedure;
procedure OnIndex( Index : longint );
begin
switch Index of
case 1;
SetColor( 'ink', 'white' );
SetColor( 'paper', 'lred' );
case 2;
SetColor( 'ink', 'lyellow' );
SetColor( 'paper', 'lgreen' );
case 3;
SetColor( 'ink', 'lcyan' );
SetColor( 'paper', 'lblue' );
case 4;
SetColor( 'ink', 'lred' );
SetColor( 'paper', 'black' );
end; (* switch *)
end_procedure;
end_multi_label;
Download: multi_label_ChangeColor.cw Převod bitové reprezentace reálného čísla s jednoduchou přesností na shortrealBitová reprezentace reálného čísla s jednoduchou přesností ve formátu definovaném podle IEEE 754 je následující: Pro reprezentovanou hodnotu reálného čísla R platí: Příklad převodu: procedure BytesToFloat( b0, b1, b2, b3 : shortcard ): shortreal;
var
b, e, m, s : longcard;
E, M : real;
i : integer;
begin
b = bitshl( b3, 24 ) + bitshl( b2, 16 ) + bitshl( b1, 8 ) + b0;
m = bitand(b, val('7FFFFF', 16 ));
e = bitshr(bitand(b, val('7F800000', 16 )), 23);
s = bitget(b, 31);
for i = 0 to 7 do
E = E + bitget( e, i ) * pow( 2, i );
M = M + bitget( m, 23 - i ) * pow( 2, -i );
end;
for i = 8 to 23 do
M = M + bitget( m, 23 - i ) * pow( 2, -i );
end;
if (E >= 1) and (E <=254) then
return pow(-1, s) * pow( 2, E-127) * (1 + M); (* basic format *)
elsif (E = 0) and (M <> 0) then
return pow(-1, s) * pow( 2, -126) * M; (* denormalized number *)
elsif (E = 0) and (M = 0) then
return 0;
elsif (E = 255) and (M = 0) then
if s = 0 then
return MaxShortReal; (* plus infinity *)
else
return MinShortReal; (* minus infinity *)
end;
else (* (E = 255) and (M > 0) *)
core.DebugOutput( 'ERROR: Invalid number mask' );
core.StopApplication();
end;
end_procedure;
Download: Float to-from Four Bytes Conversion (IEEE754 format).cw Jak zapsat hodnotu z přístroje s jedním výstupem (control, switch, apod.) na více datových elementů?Tyto přístroje mají událostní proceduru OnOutput, která je vyvolávána vždy po zadání hodnoty. Do této procedury je v parametru Output předávána právě zadaná hodnota, kterou pak můžeme jednoduše přiřadit na příslušné datové elementy. Příklad: control MyControl;
procedure OnOutput( Output : real );
begin
data_element1 = Output;
data_element2 = Output;
data_element3 = Output > 50;
...
data_elementN = k1 + Output * k2;
end_procedure;
end_control;
Jak je vidět na příkladu, lze takto na datové elementy přířadit i hodnotu získanou vyčíslením výrazu. Jak nastavit počítání čísla týdne v roce podle českých zvyklostíPokud potřebujete prohlížet archivy sledovaných veličin v přístroji data_viewer, máte možnost nastavit počátek časové osy dialogem. Datum a čas lze zadat ručně vepsáním do editačních polí, nebo lze otevřít pomocný dialog s kalendářem pro výběr dne. Možná Vás zarazilo, že v zobrazeném kalendáři nesedí čísla týdnů. Problém je v tom, že kalendář respektuje nastavení operačního systému a pokud toto není pro dané národní prostředí správné, nesouhlasí číslování týdnů. Číslování týdnů není podle všeobecně užívaného pravidla Sjednat nápravu nelze prostřednictvím okna regionálních nastavení. Ačkoliv máte nastaveno české prostředí, číslování týdnů v roce nemusí odpovídat. Příčinou je chybně nastavená položka LOCALE_IFIRSTWEEKOFYEAR tzv. locale nastavení (více informací viz MSDN ). Opravit nastavení lze např. pomocí programu Regedit, kdy v klíči HKEY_CURRENT_USER\Control Panel\International nastavíte položku iFirstWeekOfYear na hodnotu 2. Od tohoto okamžiku bude výpočet proveden podle běžných českých zvyklostí a bude stejný jako např. v tištěných kalendářích. Číslování podle českých zvyklostí |