AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

einen Datensatzmitgliedsnamen dynamisch zuweisen

Ein Thema von neumimnemecky · begonnen am 6. Jul 2022 · letzter Beitrag vom 7. Jul 2022
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
neumimnemecky

Registriert seit: 21. Dez 2018
45 Beiträge
 
#1

einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 09:58
(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:
// 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;
(English: Good morning,
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:
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;
basic.ini
[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

Geändert von neumimnemecky ( 6. Jul 2022 um 13:08 Uhr)
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 11:47
Nicht zu beantworten mit den gegebenen Infos. Zeig die Deklaration des Records und einen repäsentstiven Teil des Ini-Files.
Peter Below
  Mit Zitat antworten Zitat
neumimnemecky

Registriert seit: 21. Dez 2018
45 Beiträge
 
#3

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 12:52
Nicht zu beantworten mit den gegebenen Infos. Zeig die Deklaration des Records und einen repäsentstiven Teil des Ini-Files.
Ich habe die Frage zur Deklaration und ein Beispiel der INI-Datei hinzugefügt.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.152 Beiträge
 
Delphi 12 Athens
 
#4

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 13:34
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] = 'Bthen X := ini.basic.B;
X.path := pars[1];





Delphi-Quellcode:
//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 = 'Athen begin
  if k = 'path_Athen ini.basic.path_A := pars[1]
  else if k = 'first_frame_Athen ini.basic.first_A := pars[1]
  else if k = 'end_frame_Athen ini.basic.last_A := pars[1]
  else if k = 'first_filename_Athen ini.basic.start_name_A := pars[1]
  else if k = 'check_if_files_exist_Athen ini.basic.check_files_exist_A := true;
end else if group = 'Bthen begin
  if k = 'path_Bthen ini.basic.path_B := pars[1]
  else if k = 'first_frame_Bthen ini.basic.first_B := pars[1]
  else if k = 'end_frame_Bthen ini.basic.last_B := pars[1]
  else if k = 'first_filename_Bthen ini.basic.start_name_B := pars[1]
  else if k = 'check_if_files_exist_Bthen ini.basic.check_files_exist_B := true;
end;
end; // ein end zuviel?
wozu nochmal die group extra vergleichen, wenn die schon in K enthalten ist?
Delphi-Quellcode:
k := pars[0] + group;
if k = 'path_Athen ini.basic.path_A := pars[1]
else if k = 'first_Athen ini.basic.first_A := pars[1]
else if k = 'last_Athen ini.basic.last_A := pars[1]
else if k = 'start_name_Athen ini.basic.start_name_A := pars[1]
else if k = 'check_files_exist_Athen ini.basic.check_files_exist_A := true
else if k = 'path_Bthen ini.basic.path_B := pars[1]
else if k = 'first_Bthen ini.basic.first_B := pars[1]
else if k = 'last_Bthen ini.basic.last_B := pars[1]
else if k = 'start_name_Bthen ini.basic.start_name_B := pars[1]
else if k = 'check_files_exist_Bthen ini.basic.check_files_exist_B := true;
bzw.
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:
//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 = 'Athen begin
  if pars[0] = 'paththen ini.basic.path_A := pars[1]
  else if pars[0] = 'first_framethen ini.basic.first_A := pars[1]
  else if pars[0] = 'end_framethen ini.basic.last_A := pars[1]
  else if pars[0] = 'first_filenamethen ini.basic.start_name_A := pars[1]
  else if pars[0] = 'check_if_files_existthen ini.basic.check_files_exist_A := true;
end else if group = 'Bthen begin
  if k = 'paththen ini.basic.path_B := pars[1]
  else if pars[0] = 'first_framethen ini.basic.first_B := pars[1]
  else if pars[0] = 'end_framethen ini.basic.last_B := pars[1]
  else if pars[0] = 'first_filenamethen ini.basic.start_name_B := pars[1]
  else if pars[0] = 'check_if_files_existthen ini.basic.check_files_exist_B := true;
end;
bzw.
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;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Jul 2022 um 13:43 Uhr)
  Mit Zitat antworten Zitat
neumimnemecky

Registriert seit: 21. Dez 2018
45 Beiträge
 
#5

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 17:04
Danke, aber
"IndexText" Problem in der D7 [Error]: Undeclared identifier: 'IndexText'.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.152 Beiträge
 
Delphi 12 Athens
 
#6

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 17:17
Problem in der D7
Wer macht denn sowas?

https://www.embarcadero.com/de/products/delphi/starter

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?
Aktuell ist es in der System.StrUtils bzw. StrUtils ... aber mit der Zeit wurden auch Units umbenannt, bzw. Funktion in andere Units verschoben.

Delphi-Referenz durchsuchenStrUtils.IndexText (case-insensitive, also quasi mit einem AnsiUpperCase drumrum)
Delphi-Referenz durchsuchenStrUtils.IndexStr (case-sensitive)
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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Jul 2022 um 17:19 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.418 Beiträge
 
Delphi 7 Professional
 
#7

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 17:36
Delphi 7 kennt aber AnsiIndexText (in der Unit StrUtils zu finden).
  Mit Zitat antworten Zitat
neumimnemecky

Registriert seit: 21. Dez 2018
45 Beiträge
 
#8

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 18:09
Viele Danke, daher habe ich den Code ein wenig geändert, um die Leistung zu steigern:

Code:
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;
Es ist eine schöne Lösung.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.152 Beiträge
 
Delphi 12 Athens
 
#9

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 18:29
(pars[0]+'_B', ['path_B' , 'first_frame_B' , ...

(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 123: als Konstante oder mit {Name}123: , erspart sich, da der Kommentar/Name bereits als .path := dran steht.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Jul 2022 um 18:36 Uhr)
  Mit Zitat antworten Zitat
neumimnemecky

Registriert seit: 21. Dez 2018
45 Beiträge
 
#10

AW: einen Datensatzmitgliedsnamen dynamisch zuweisen

  Alt 6. Jul 2022, 18:42
(pars[0]+'_B', ['path_B' , 'first_frame_B' , ...

(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 123: als Konstante oder mit {Name}123: , erspart sich, da der Kommentar/Name bereits als .path := dran steht.

Den letzten Satz verstehe ich nicht. Aber eine Millisekunde langsamer wäre viel. Hatten Sie nicht eine Mikrosekunde im Sinn?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz