@Observer2323 Poradziłeś sobie, sprawdziłeś to co dałem wyżej?
Widzę że @furious programming dał dobry patent, a mianowicie programowanie generyczne
Można też skorzystać z generycznego iteratora i pętli for in:
Kopiuj
procedure AssignToOneValue<T>(const Value: T; const Values: array of T);
var
I: T;
begin
for I in Values do
I^ := Value^;
end;
Dobry pomysl, ale nie zadziala na starszych wersjach Delphi :) Nie wiem nawet czy i nie na nowych, bo iteracja nie jest do konca poprawna.
Pomogę 
Załóżny że nasza głowna forma (formualrz) nazwiemy MainForm, a przycisk na nim TestBtn
Teraz tak, ważne aby do Uses dodać:
Kopiuj
System.SysUtils, System.Rtti, System.TypInfo;
następnie
Kopiuj
type
PVariant = ^Variant;
via
Kopiuj
type
PVariant = ^Variant;
type
TMainForm = class(TForm)
TestBtn: TButton;
procedure TestBtnClick(Sender: TObject);
private
{ Private declarations }
procedure AssignToMultipleVars<T>(const Value: T; const Values: array of PVariant);
public
{ Public declarations }
end;
Proszę bardzo kod:
Kopiuj
// Generyczna procedura do przypisywania wartości do wielu zmiennych
procedure TMainForm.AssignToMultipleVars<T>(const Value: T; const Values: array of PVariant);
var
i: Integer;
ctx: TRttiContext;
rttiType: TRttiType;
v: Variant;
val: TValue;
begin
ctx := TRttiContext.Create;
try
rttiType := ctx.GetType(TypeInfo(T));
val := TValue.From<T>(Value);
// Sprawdzenie typu za pomocą RTTI i przypisanie odpowiedniego typu do Variant
case rttiType.TypeKind of
tkInteger, tkInt64: // Integer
v := val.AsInteger;
tkUString, tkString, tkChar, tkWChar: // String
v := val.ToString;
tkFloat: // Float
v := val.AsExtended;
// mozemy dodac inne
else
raise Exception.Create('Unsupported type for assignment to Variant');
end;
// Przypisujemy wartość do zmiennych PVariant
for i := Low(Values) to High(Values) do
begin
if Assigned(Values[i]) then
Values[i]^ := v;
end;
finally
ctx.Free;
end;
end;
procedure TMainForm.TestBtnClick(Sender: TObject);
var
a, b, c, d: Variant;
s: Variant;
f: Variant;
msgTxt: string;
begin
// Przypisanie wartości 10 do wszystkich zmiennych całkowitych jednocześnie
AssignToMultipleVars<Integer>(10, [@a, @b, @c, @d]);
// Przypisanie wartości do zmiennej string
AssignToMultipleVars<string>('Test', [@s]);
// Przypisanie wartości do zmiennej zmiennoprzecinkowej
AssignToMultipleVars<Double>(12.3, [@f]);
// sprawdzamy wersje Delphi
{$IF CompilerVersion >= 36} // Delphi 12 Athens lub nowszy
// Zmiana formatowania z użyciem explicit konwersji
msgTxt := Format(
'Wartości a: %d, b: %d, c: %d, d: %d, s: %s, f: %f',
[Integer(a), Integer(b), Integer(c), Integer(d), string(s), Double(f)]
);
{$ELSE}
// w nowszych wersjach powinno zadzialac
msgTxt := Format(
'Wartości a: %d, b: %d, c: %d, d: %d, s: %s, f: %f',
[a, b, c, d, s, f]
{$IFEND}
// wyswietl wartosci
ShowMessage(msgTxt);
end;
Wrzucilem cały kod, jak ktoś chce może pobrać: KLIK
EDIT:
Jak ktoś ogarnia Assembler'a, możemy użyć ASM
Kopiuj
procedure TMainForm.AssignIntToMultipleVars(const Value: Integer; const Values: array of PVariant);
asm
// EAX zawiera Value
// EDX zawiera wskaźnik do tablicy Values
// ECX zawiera długość tablicy Values
push esi
push edi
mov esi, edx // ESI wskazuje na tablicę Values
mov edi, ecx // EDI to licznik pętli
@loop:
test edi, edi
jz @done
mov edx, [esi] // Załaduj adres PVariant do EDX
test edx, edx // Sprawdź, czy wskaźnik nie jest nil
jz @next
mov [edx], eax // Przypisz wartość (EAX) do Variant
@next:
add esi, 4 // Przesuń wskaźnik na następny element tablicy
dec edi // Zmniejsz licznik
jmp @loop
@done:
pop edi
pop esi
end;