![]() |
einen Datensatzmitgliedsnamen dynamisch zuweisen
(to assign a record member name dynamically)
Guten Tag, Ich suche Hilfe, um diesen Code zu vereinfachen und die aus der INI-Datei gelesenen Werte einer Variablen vom Typ "Datensatz" zuzuweisen, wobei sich der Elementname vom Schlüsselnamen in der INI-Datei unterscheidet. Ich habe nicht herausgefunden, wie ich den Mitgliedsnamen dynamisch zuweisen kann, da es zwei Gruppen (A und B) mit denselben Schlüsselnamen in der Datei, aber unterschiedlichen Namen im Datensatz gibt.
Code:
(English: Good morning,
// ini file contains pairs key_name=value , the record contains abbreviated key name
if pars[0] = 'first_frame' then k := 'first_'+group else if pars[0] = 'end_frame' then k := 'last_'+group else if pars[0] = 'first_filename' then k := 'start_name_'+group else if pars[0] = 'path' then k := 'path_'+group else if pars[0] = 'check_if_files_exist' then k := 'check_files_exist_'+group; if group = 'A' then begin if k = 'path_A' then ini.basic.path_A := pars[1] else if k = 'first_A' then ini.basic.first_A := pars[1] else if k = 'last_A' then ini.basic.last_A := pars[1] else if k = 'start_name_A' then ini.basic.start_name_A := pars[1] else if k = 'check_files_exist_A' then ini.basic.check_files_exist_A := true; end else if group = 'B' then begin if k = 'path_B' then ini.basic.path_B := pars[1] else if k = 'first_B' then ini.basic.first_B := pars[1] else if k = 'last_B' then ini.basic.last_B := pars[1] else if k = 'start_name_B' then ini.basic.start_name_B := pars[1] else if k = 'check_files_exist_B' then ini.basic.check_files_exist_B := true; end; end; I'm looking for help to simplify this code, assigning the values read from ini file to a variable of type Record, where the member name is different from the name of the key in the ini file. I haven't figured out how can I assign the member name dynamically because there are two groups (A and B) with the same key names in the file but different names in the record.) Deklaration:
Code:
basic.ini
type TBasicSettings = record
is_scroll_vertical: boolean; scroll_type=vertical is_image_direction_up: boolean; is_search_colors_HSL: boolean; path_A: string; path_B: string; check_files_exist_A: boolean; check_files_exist_B: boolean; RAM_disk: string; RAM_free: LongWord; start_name_A: string;first_filename first_A: string;first_frame last_A: string;end_frame= start_name_B: string;first_filename first_B: string;first_frame last_B: string;end_frame fps: byte; scroll_max_shift: integer; end; [GENERAL]
Code:
[GENERAL]
scroll_type=vertical image_direction=up search_colors_in=HSL H_max_difference_deg=10% S_max_difference_per=20% L_max_difference_per=10% ;V_max_difference_per=10% padding_left=22 padding_right=25 padding_top=0 padding_bottom=0 detect_max_character_count_on_screen=3 arrow_1_count=2 arrow_2_count=1 arrow_3_count=1 image_1_count=1 skip_detections_on_screen_when_frame_position_is_determined=1 group_to_copy_image_data_from=A text_copy_color_direction=BA RAM_disk=A: RAM_disk_free_space=1GB |
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Nicht zu beantworten mit den gegebenen Infos. Zeig die Deklaration des Records und einen repäsentstiven Teil des Ini-Files.
|
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Zitat:
|
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Die Datenstruktur ändern
und gleiche Teile zusammenfassen? (und dann nachfolgend den größten Teil ignorieren)
Delphi-Quellcode:
// nicht
ini.basic.path_A := pars[1] ini.basic.path_B := pars[1] // sondern ini.basic.A.path := pars[1] ini.basic.B.path := pars[1] // für Objekte statt Records ... bei Records andersrum, also erst den Temp-Record füllen und dann zuweisen if pars[0] = 'B' then X := ini.basic.B; X.path := pars[1];
Delphi-Quellcode:
wozu nochmal die group extra vergleichen, wenn die schon in K enthalten ist?
//if pars[0] = 'first_frame' then k := 'first_'+group
//else if pars[0] = 'end_frame' then k := 'last_'+group //else if pars[0] = 'first_filename' then k := 'start_name_'+group //else if pars[0] = 'path' then k := 'path_'+group //else if pars[0] = 'check_if_files_exist' then k := 'check_files_exist_'+group //else ; // was ist k, wenn nichts trifft? // wozu den ersten Teil umbennen? // sowas würde sich nur lohnen, wenn du anschließend mit diesen Namen via RTTI nach den Feldern suchen tätest. TRTTIContext.Create.GetType(TIniBasicRecordIrgendwas).GetField(k).SetValue(ini.basic, pars[1]); // abgesehn vom check_if_files_exist // es gibt auch Funktionen/Klassen/Frameworks, z.B. für INI/XML/JSON zu Record/Klasse, auch inkl. Umbenennen von SpeicherName zu FeldName k := pars[0] + group; if group = 'A' then begin if k = 'path_A' then ini.basic.path_A := pars[1] else if k = 'first_frame_A' then ini.basic.first_A := pars[1] else if k = 'end_frame_A' then ini.basic.last_A := pars[1] else if k = 'first_filename_A' then ini.basic.start_name_A := pars[1] else if k = 'check_if_files_exist_A' then ini.basic.check_files_exist_A := true; end else if group = 'B' then begin if k = 'path_B' then ini.basic.path_B := pars[1] else if k = 'first_frame_B' then ini.basic.first_B := pars[1] else if k = 'end_frame_B' then ini.basic.last_B := pars[1] else if k = 'first_filename_B' then ini.basic.start_name_B := pars[1] else if k = 'check_if_files_exist_B' then ini.basic.check_files_exist_B := true; end; end; // ein end zuviel?
Delphi-Quellcode:
bzw.
k := pars[0] + group;
if k = 'path_A' then ini.basic.path_A := pars[1] else if k = 'first_A' then ini.basic.first_A := pars[1] else if k = 'last_A' then ini.basic.last_A := pars[1] else if k = 'start_name_A' then ini.basic.start_name_A := pars[1] else if k = 'check_files_exist_A' then ini.basic.check_files_exist_A := true else if k = 'path_B' then ini.basic.path_B := pars[1] else if k = 'first_B' then ini.basic.first_B := pars[1] else if k = 'last_B' then ini.basic.last_B := pars[1] else if k = 'start_name_B' then ini.basic.start_name_B := pars[1] else if k = 'check_files_exist_B' then ini.basic.check_files_exist_B := true;
Delphi-Quellcode:
case IndexText(pars[0] + group, ['path_A', 'first_A', 'last_A' , 'start_name_A' , 'check_files_exist_A' , 'path_B' , 'first_B' , 'last_B' , 'start_name_B', 'check_files_exist_B']) oF
0: ini.basic.path_A := pars[1]; 1: ini.basic.first_A := pars[1]; 2: ini.basic.last_A := pars[1]; 3: ini.basic.start_name_A := pars[1]; 4: ini.basic.check_files_exist_A := true; 5: ini.basic.path_B := pars[1]; 6: ini.basic.first_B := pars[1]; 7: ini.basic.last_B := pars[1]; 8: ini.basic.start_name_B := pars[1]; 9: ini.basic.check_files_exist_B := true; end; oder wozu unnötig umbenennen (Group anhängen), wenn die Groups eh getrennt behandelt werden?
Delphi-Quellcode:
bzw.
//if pars[0] = 'first_frame' then k := 'first'
//else if pars[0] = 'end_frame' then k := 'last' //else if pars[0] = 'first_filename' then k := 'start_name' //else if pars[0] = 'path' then k := 'path' //else if pars[0] = 'check_if_files_exist' then k := 'check_files_exist'; if group = 'A' then begin if pars[0] = 'path' then ini.basic.path_A := pars[1] else if pars[0] = 'first_frame' then ini.basic.first_A := pars[1] else if pars[0] = 'end_frame' then ini.basic.last_A := pars[1] else if pars[0] = 'first_filename' then ini.basic.start_name_A := pars[1] else if pars[0] = 'check_if_files_exist' then ini.basic.check_files_exist_A := true; end else if group = 'B' then begin if k = 'path' then ini.basic.path_B := pars[1] else if pars[0] = 'first_frame' then ini.basic.first_B := pars[1] else if pars[0] = 'end_frame' then ini.basic.last_B := pars[1] else if pars[0] = 'first_filename' then ini.basic.start_name_B := pars[1] else if pars[0] = 'check_if_files_exist' then ini.basic.check_files_exist_B := true; end;
Delphi-Quellcode:
i := IndexText(pars[0] + group, ['path', 'first', 'last', 'start_name', 'check_files_exist']);
case group of 'A': case i oF 0: ini.basic.path_A := pars[1]; 1: ini.basic.first_A := pars[1]; 2: ini.basic.last_A := pars[1]; 3: ini.basic.start_name_A := pars[1]; 4: ini.basic.check_files_exist_A := true; end; 'B': case i oF 0: ini.basic.path_B := pars[1]; 1: ini.basic.first_B := pars[1]; 2: ini.basic.last_B := pars[1]; 3: ini.basic.start_name_B := pars[1]; 4: ini.basic.check_files_exist_B := true; end; end; |
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Danke, aber
"IndexText" Problem in der D7 [Error]: Undeclared identifier: 'IndexText'. |
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Zitat:
![]() Diese Funktionen gibt es bestimmt mindestens seit 2009 2006, also kurz nach D7, aber vielleicht auch schon im Delphi 7, wenn man die passende Unit einbindet? :angle: Aktuell ist es in der System.StrUtils bzw. StrUtils ... aber mit der Zeit wurden auch Units umbenannt, bzw. Funktion in andere Units verschoben. ![]() ![]() Die gucken einfach nur in einem Array, ob/wo das da drin steht. CASE kann ja leider im Delphi nur Ordinal und keine Strings, so wie nahezu jede andere Sprache :cry: |
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Delphi 7 kennt aber AnsiIndexText (in der Unit StrUtils zu finden).
|
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Viele Danke, daher habe ich den Code ein wenig geändert, um die Leistung zu steigern:
Code:
Es ist eine schöne Lösung.
if group = 'A' then
case AnsiIndexText(pars[0]+'_A', ['path_A', 'first_frame_A', 'end_frame_A' , 'first_filename_A' , 'check_if_files_exist_A']) oF 0: ini.basic.A.path := pars[1]; 1: ini.basic.A.first := pars[1]; 2: ini.basic.A.last := pars[1]; 3: ini.basic.A.start_name := pars[1]; 4: ini.basic.A.check_files_exist := true; end else if group = 'B' then case AnsiIndexText(pars[0]+'_B', ['path_B' , 'first_frame_B' , 'end_frame_B' , 'first_filename_B', 'check_if_files_exist_B']) oF 0: ini.basic.B.path := pars[1]; 1: ini.basic.B.first := pars[1]; 2: ini.basic.B.last := pars[1]; 3: ini.basic.B.start_name := pars[1]; 4: ini.basic.B.check_files_exist := true; end; |
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Delphi-Quellcode:
(pars[0]+'_B', ['path_B' , 'first_frame_B' , ...
Delphi-Quellcode:
:stupid:
(pars[0], ['path' , 'first_frame' , ...
Schneller ist es nur bedingt ... eher fast gleich schnell oder vielleicht eine Millisekunde langsamer (ein Funktionsaufruf, aber gleich viele String-Vergleiche), aber es macht den Code kürzer und ohne die viele IF....THEN dazwischen auch etwas übersichlicher. Hier die
Delphi-Quellcode:
als Konstante oder mit
123:
Delphi-Quellcode:
, erspart sich, da der Kommentar/Name bereits als
{Name}123:
Delphi-Quellcode:
dran steht.
.path :=
|
AW: einen Datensatzmitgliedsnamen dynamisch zuweisen
Zitat:
Den letzten Satz verstehe ich nicht. Aber eine Millisekunde langsamer wäre viel. Hatten Sie nicht eine Mikrosekunde im Sinn? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz