おせわになっております。
年月日時分秒をパック10進数形式のバイト配列で返す関数の戻り値を、
呼び出し側で、バイト配列の途中に代入するようなことはできますでしょうか。
また、関数の書き方についても、怪しい点があれば教えてください。
【呼び出し側】
var
B:array[0..7] of byte;
begin
B[0] := $FF;
//↓こんな感じの代入がやりたいのですが…エラーになります。
B[1..6] := PFNowTo6Byte();
B[7] := $FF;
showmessage(
'■' + IntToHex(result[0],2)
+ '-' + IntToHex(result[1],2)
+ '-' + IntToHex(result[2],2)
+ '-' + IntToHex(result[3],2)
+ '-' + IntToHex(result[4],2)
+ '-' + IntToHex(result[5],2)
+ '-' + IntToHex(result[6],2)
+ '-' + IntToHex(result[7],2) + '■'
);
// 2004/05/25 12:30:58 の場合
//「■FF-04-05-25-12-30-58-FF■」と表示させたいのです
────────────────────────
//※TByteArray: array of Byte;
function TForm1.PFNowTo6Byte: TByteArray;
var
UsStr :String;
UsInt :Integer;
begin
UsStr := FormatDateTime('yymmddhhnnss',Now);
Val( '$' + Copy(UsStr, 1,2), result[0], UsInt);
Val( '$' + Copy(UsStr, 3,2), result[1], UsInt);
Val( '$' + Copy(UsStr, 5,2), result[2], UsInt);
Val( '$' + Copy(UsStr, 7,2), result[3], UsInt);
Val( '$' + Copy(UsStr, 9,2), result[4], UsInt);
Val( '$' + Copy(UsStr,11,2), result[5], UsInt);
end;
────────────────────────
こんな感じです。
type
TByteArray = array of Byte;
function PFNowTo6Byte: TByteArray;
var
UsStr :String;
UsInt :Integer;
begin
SetLength(result,6);
UsStr := FormatDateTime('yymmddhhnnss',Now);
Val(Copy(UsStr, 1,2), result[0], UsInt);
Val(Copy(UsStr, 3,2), result[1], UsInt);
Val(Copy(UsStr, 5,2), result[2], UsInt);
Val(Copy(UsStr, 7,2), result[3], UsInt);
Val(Copy(UsStr, 9,2), result[4], UsInt);
Val(Copy(UsStr,11,2), result[5], UsInt);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
B:TByteArray;
begin
B := PFNowTo6Byte;
Label1.Caption := Format('■FF-%.2d-%.2d-%.2d-%.2d-%.2d-%.2d-FF■',
[B[0],B[1],B[2],B[3],B[4],B[5]]);
end;
おっと
> バイト配列の途中に代入するには
でしたね。地道に代入すると
type
TByteArray = array of Byte;
function PFNowTo6Byte: TByteArray;
var
UsStr :String;
UsInt :Integer;
begin
SetLength(result,6);
UsStr := FormatDateTime('yymmddhhnnss',Now);
Val(Copy(UsStr, 1,2), result[0], UsInt);
Val(Copy(UsStr, 3,2), result[1], UsInt);
Val(Copy(UsStr, 5,2), result[2], UsInt);
Val(Copy(UsStr, 7,2), result[3], UsInt);
Val(Copy(UsStr, 9,2), result[4], UsInt);
Val(Copy(UsStr,11,2), result[5], UsInt);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
B:TByteArray;
C:array [0..7] of Byte;
i:integer;
begin
B := PFNowTo6Byte;
C[0] := $FF;
for i := 1 to 6 do C[i] := B[i-1];
C[7] := $FF;
Label1.Caption := Format('■%.2x-%.2d-%.2d-%.2d-%.2d-%.2d-%.2d-%.2x■',
[C[0],C[1],C[2],C[3],C[4],C[5],C[6],C[7]]);
end;
> バイト配列の途中に代入するには
ですが、上の
for i := 1 to 6 do C[i] := B[i-1];
のかわりに
Move(B[0],C[1],6);
も使えますね。
ひとスジ : 「動的配列って ホントはポインタだってこと知っとった?」
ふたスジ : 「知らんかった〜」
ひとスジ : 「だからこんなことできるの知っとった?」
ふたスジ : 「知らんかった〜」
type
TByteArray = array of Byte;
function PFNowTo6Byte(var C: TByteArray): TByteArray;
var
UsStr : String;
UsInt : Integer;
begin
UsStr := FormatDateTime('yymmddhhnnss', Now);
Val('$'+ Copy(UsStr, 1,2), C[1], UsInt);
Val('$'+ Copy(UsStr, 3,2), C[2], UsInt);
Val('$'+ Copy(UsStr, 5,2), C[3], UsInt);
Val('$'+ Copy(UsStr, 7,2), C[4], UsInt);
Val('$'+ Copy(UsStr, 9,2), C[5], UsInt);
Val('$'+ Copy(UsStr,11,2), C[6], UsInt);
result := TByteArray(@C[1]); // Cの一部分をBにする
end;
procedure TForm1.Button1Click(Sender: TObject);
var
B: TByteArray;
C: TByteArray;
begin
SetLength(B, 6);
SetLength(C, 8);
B := PFNowTo6Byte(C);
C[0] := $FF;
C[7] := $FF;
Label1.Caption := Format('■%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x■',
[C[0],C[1],C[2],C[3],C[4],C[5],C[6],C[7]]);
Label2.Caption := Format('■FF-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-FF■',
[B[0],B[1],B[2],B[3],B[4],B[5]]);
end;
ふたスジ : 「ンなら、オマエのお菓子 オレが食べちゃったの知っとった?」
ひとスジ : 「知らんかった〜」
> ひとスジ : 「動的配列って ホントはポインタだってこと知っとった?」
そうですね。string 型に似てますよね。
> result := TByteArray(@C[1]); // Cの一部分をBにする
なるほど、これは値を代入するのではなく、参照を代入する感じですね。
だとすると、長い配列の一部を受け取る短い配列の
SetLength(B, 6);
はいりませんね。実体は必要ないですから。参照が代入されている様子を
見てみましょう。
procedure TForm1.Button1Click(Sender: TObject);
var
B,C:TByteArray;
begin
SetLength(C,3);
C[0] := $FF;
C[1] := $AA;
C[2] := $FF;
B := TByteArray(@C[1]);
Memo1.Lines.Add(IntToHex(B[0],2));
C[1] := $BB;
Memo1.Lines.Add(IntToHex(B[0],2));
end;
こんなふうにすると、Memo1 には
AA
BB
と表示されて、B[0] が C[1] と同じ場所を参照しているのが分かりますね。
わたしの回答は「代入」を値のコピーとして解釈したものです。
それから、今日の日付は26日ですけど、
> Val('$'+ Copy(UsStr, 5,2), C[3], UsInt);
にすると16進の26、つまり10進の38が C[3] に代入されますね。
表示のとき、16進数にしているので見かけは同じですが、十進数として
格納し、表示も10進数表示にするのが理にかなっているように思います。
ありがとうございました。
関数をやめて以下のような手続きにしました。
【呼び出し側】
var
DAT :array[120] of Byte;
UsIdx :Integer;
Begin
UsIdx := 0;
//…
UsIdx := UsIdx + 14;
Set_Now6Byte( DAT, UsIdx);
────────────────────────────────
// 年月日時分秒6バイト
procedure TMain_F.Set_Now6Byte(var ArByt: TByteArray; ArIdx: integer);
var
UsStr : String;
UsInt : Integer;
begin
UsStr := FormatDateTime('yymmddhhnnss', Now);
Val('$'+ Copy(UsStr, 1,2), ArByt[ArIdx + 0], UsInt);
Val('$'+ Copy(UsStr, 3,2), ArByt[ArIdx + 1], UsInt);
Val('$'+ Copy(UsStr, 5,2), ArByt[ArIdx + 2], UsInt);
Val('$'+ Copy(UsStr, 7,2), ArByt[ArIdx + 3], UsInt);
Val('$'+ Copy(UsStr, 9,2), ArByt[ArIdx + 4], UsInt);
Val('$'+ Copy(UsStr,11,2), ArByt[ArIdx + 5], UsInt);
end;
ツイート | ![]() |