みんなに優しく、解りやすくをモットーに開設しています。 以下のルールを守りみんなで助け合いましょう。
1.ファイルメーカーで解らない事があればここで質問して下さい。 何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)
You are not logged in.
いつもお世話になっております。下記のような改行区切で列の区切りはカンマを使用しているリストの行と列を入れ替える方法をお教えください。
品名,数量,金額
いちご,5,3970
みかん,20,760
バナナ,20,2640
リンゴ,10,1760
梨,14,4720
↓
品名,いちご,みかん,バナナ,リンゴ,梨
数量,5,20,20,10,14
金額,3970,760,2640,1760,4720
定かでありませんが昔loop処理で出来たような記憶があったので、全て一列に変換しwhileを使って再構成すればと思ったのですが上手くwhile式を作れませんでした。
作業環境;windows11 FilemakerPro20.2.1.60
宜しくお願いいたします。
一応、下記の計算式で
Let([e =Pow::a1;
d = ValueCount(Substitute(GetValue (e;1);"," ; ¶ ));
n = ValueCount (e);
b = Substitute ( e ;"," ; ¶ )
];
While ( [ aa = "";z =0 ] ; z < d ; [aa=aa&While ([ ab = ""; i = 0;k = 1] ; k ≤ n; [ ab = ab&GetValue ( b ; i + z+1) & ",";i = i + 3;k= K+1 ]; ab )&¶;z = z+1] ; Substitute ( aa ; ",¶" ; ¶ ))
)
↓
品名,いちご,みかん,バナナ,リンゴ,梨
数量,5,20,20,10,14
金額,3970,760,2640,1760,4720
の結果を得ましたがwhileの入れ子の方法が正しいのかどうか分かりません
読み切れてませんが、
i = i + 3
のところは3でなくdを使うべき?
himadaneeさんご指摘ありがとうございます。
変数に置き変えるのを忘れていました。
3列限定なら、
While (
[
t = text ;
n = ValueCount ( Substitute ( GetValue ( t ; 1 ) ; "," ; ¶ ) ) ;
i = 1 ;
$R[1] = "" ;
$R[2] = "" ;
$R[3] = "" ;
tn = t
] ;
not IsEmpty ( tn ) ;
[
tn = GetValue ( t ; i ) ;
$R[1] = List ( $R[1] ; GetValue ( Substitute ( tn ; "," ; ¶ ) ; 1 ) ) ;
$R[2] = List ( $R[2] ; GetValue ( Substitute ( tn ; "," ; ¶ ) ; 2 ) ) ;
$R[3] = List ( $R[3] ; GetValue ( Substitute ( tn ; "," ; ¶ ) ; 3 ) ) ;
i = i + 1
] ;
List (
Substitute ( $R[1] ; ¶ ; "," ) ;
Substitute ( $R[2] ; ¶ ; "," ) ;
Substitute ( $R[3] ; ¶ ; "," )
)
)
汎用にするのでしたら、繰り返しているところを内包するwhile()で処理します。
Offline
3列に限定しているわけではありませんが、shinさんの計算式だと下記のようなまずあり得ない例外テキストを処理しようとすれば
品名,数量,金額
いちご,,3970
みかん,20,760
バナナ,20,2640
リンゴ,10,1760
梨,14,4720
↓
品名,いちご,みかん,バナナ,リンゴ,梨
数量,20,20,10,14
金額,3970,760,2640,1760,4720
となり2行目の列位置が右に詰まりずれてしまいます。
私の方法でも
品名,いちご,みかん,バナナ,リンゴ,梨
数量,,20,20,10,14
金額,3970,760,2640,1760,4720
となり空白を明確に示すわけではないので、今回の質問以前に、最初のテキストを作る段階から再考する必要がありそうです。
>汎用にするのでしたら、繰り返しているところを内包するwhile()で処理します。
当初の質問は、この繰り返しているところを内包するwhile()で処理するところが出来なかったことで、次に#2の入れ子方法の作り方が本当に正しいのか解っていないことです。
「空白を明確に示すわけではない」とはどういう意味でしょう。
元のデータで空白データは何も入れない(「,,」とカンマが連続)で記述してるので、結果でも同様にするしかないと思いますが
mergeみたいにテキストを""で囲むとしても数値の場合はそうしないでしょう。
あとは、テキストデータにカンマ(改行もか)が含まれる場合の処理を考える必要があるのかどうか。
とりあえず、汎用にした式は、while() を入れ子にして、
While (
[
t = text ;
n = ValueCount ( Substitute ( GetValue ( t ; 1 ) ; "," ; ¶ ) ) ;
i = 1 ;
dummy = While (
[
$i = n
] ;
$i ;
[
$R[$i] = "" ;
$i = $i - 1
] ;
$i
) ;
tn = t
] ;
not IsEmpty ( tn ) ;
[
tn = GetValue ( t ; i ) ;
dummy = While (
[
$i = n
] ;
$i ;
[
$R[$i] = $R[$i] & "," & GetValue ( Substitute ( tn ; "," ; ¶ ) ; $i ) ;
$i = $i - 1
] ;
$i
) ;
i = i + 1
] ;
While (
[
$i = n ;
r = ""
] ;
$i ;
[
r = List ( Replace ( $R[$i] ; 1 ; 1 ; "" ) ; r ) ;
$i = $i - 1
] ;
r
)
)
です。,, のときの処理は、List() 使っていたためです。(想定していなかったので)
修正しました。
Last edited by Shin (2023-11-12 10:37:50)
Offline
確かpowershell の場合は、$emptyの形で空白を明示的に示すなどがあったこと思ったが?
>テキストデータにカンマ(改行もか)が含まれる場合の処理を考える必要があるのかどうか。
改行までは考えなかったが、カンマの事は、「|」で区切り文字を変更するとか、テキストを作る段階で文字列をダブルクォートで囲み「,"」を改行で置換えする方法にするとか考えていました。
shinさん修正方法の計算結果
品名,いちご,みかん,バナナ,リンゴ,梨,
数量,,20,20,10,14,
金額,3970,760,2640,1760,4720,
備考,p,s,p,s,s,
となり行末カンマの処理が必要となりますがSubstituteで対処すればいいですよね
>確かpowershell の場合は、$emptyの形で空白を明示的に示すなどがあったこと思ったが?
そういうことを考えるなら、作成したデータの用途を先に示さないとだめですね。
何も書いてなければFMでインポートできる一般的なCSVを作る、としか考えませんが
>行末カンマの処理
全部作った後で処理しようとすると、最後の項目のデータが空なのかどうかの判断が必要になって面倒でしょう。
訂正
>確かpowershell の場合は、$emptyの形で空白を明示的に示すなどがあったこと思ったが?
としていたが下記のテキストをpowershellを使いexcelに書き込んだ場合問題なく所定のセルが空白となったので別に明示する必要はありませんでした。
品名,数量,金額,備考
いちご,,3970,p
While (
[
t = text ;
n = ValueCount ( Substitute ( GetValue ( t ; 1 ) ; "," ; ¶ ) ) ;
dummy =
While (
[
$i = n
] ;
$i ;
[
$R[$i] = GetValue ( Substitute ( GetValue ( t ; 1 ) ; "," ; ¶ ) ; $i ) ;
$i = $i - 1
] ;
$i
) ;
i = 2
] ;
not IsEmpty ( GetValue ( t ; i ) ) ;
[
dummy =
While (
[
$i = n
] ;
$i ;
[
$R[$i] = $R[$i] & "," & GetValue ( Substitute ( GetValue ( t ; i ) ; "," ; ¶ ) ; $i ) ;
$i = $i - 1
] ;
$i
) ;
i = i + 1
] ;
While (
[
$i = n ;
r = ""
] ;
$i ;
[
r = List ( $R[$i] ; r ) ;
$i = $i - 1
] ;
r
)
)
ですっきりしました。
Offline
shinさんありがとうございます。
正直私の方法みたいにloop処理の流れをwhileの入れ子にするのは正しいかどうか分かりませんがなんとなく流れとしては分かりますが、shinさんのwhile式の構造はすぐ理解が出来ないので戸惑っています。時間をかけ理解するよう務めます。
何回もの修正に感謝します。
koko009さんの考え方は、1,2,3¶4,5,6を1¶2¶3¶4¶5¶6 にしておき(GetValue()が使えるように)、14¶25¶36の形にピックアップする方法ですね。最初に同じものを作って一応動いたのですが、綺麗な形にならなかったので、全く違う形へ書き換えました。
各列毎に変数へデータを格納していき、最後にそれを改行区切りでまとめています。繰り返し変数を使うのが味噌です。
また、違う方法として、最初に¶を列数だけ作り、Replace() で¶を置き換えてデータを入れ込んでいく方法も面白いかも。
Last edited by Shin (2023-11-13 10:37:03)
Offline
1列に並べて取り出す方法なら、ループが1段な方が素直だろうと思って考えてみました。
While([
t=text;
row=GetValue(t;1);
nc=PatternCount(row;",")+1;
nr=ValueCount(t);
t=Substitute(t;",";¶);
i=1;
re="";
l=nc*(nr-1);
end=nc*nr
];
i<=end;
[
re=re&GetValue(t;i)&Case(i>l;¶;",");
i=i+nc-Case(i=end;0;i>l;end-1)
];
re
)
終了条件(というかCase関数のカウンタを次の列の1行目に戻す処理)が1つにならず、ちょっとすっきりしない...
1pathでの計算式 やっと綺麗になった
While (
[
t = text ;
nc = PatternCount ( GetValue ( t ; 1 ) ; "," ) + 1 ;
nr = ValueCount ( t ) ;
t = Substitute( t ; "," ; ¶ ) ;
i = 0 ;
re = ""
] ;
i < nc * nr ;
[
j = Mod ( i ; nr ) * nc + Div ( i ; nr ) + 1 ;
i = i + 1 ;
re = re & GetValue ( t ; j ) & Case ( i = nc * nr ; "" ; Mod ( i ; nr ) ; "," ; ¶ )
] ;
re
)
Last edited by Shin (2023-11-14 15:42:37)
Offline
様々な解法があり興味が尽きませんが、再度訂正です。
#12で
下記のテキストをpowershellを使いexcelに書き込んだ場合問題なく所定のセルが空白となったので別に明示する必要はありませんでした。
品名,数量,金額,備考
いちご,,3970,p
としていましたがデータをpowershellで2次元配列のオブジェクトに変換しExcelに書き出す方法では問題なく所定のセルが空白になりましたが、1次元配列をそのまま読み込まる方法では右側の値が読み込まれなく左に列がずれてしまいました。しかし、配列データを("個数","",$empty,"5","8")とすれば空白セルを正しく得られました。
以上今回の質問内容とかけ離れていますが訂正報告です。
1次元配列をそのまま読み込まる方法
↓
1次元配列をそのまま書き出す方法
に文言訂正
クオーテーションは必要ですか。
同じ式にしておいて、最後に
Substitute (
“\”” & r & “\”” ;
[ “,” ; “\”,\””];
[ “\”\”” ; “$empty”]
)
Offline
ありがとうございます。ちなみに今試していることは
filemaker側でテキストを下記のようにpowershellのコードに組み込みeventを送信スクリプトでpowershellをを実行させExcelの任意のセル範囲に書き出す事です。
*空白があるデータ・・・文字列と数字が混在していますが、1次元、2次元配列のどちらの方法でも所定のセルが空白になりまた「””」括りの数字でもExcelでは数字となっています。
<#セルに書き込むためのデータ#>
$array1 = @("果物","リンゴ" ,"ミカン", "バナナ","ぶどう")
$array2 = @("個数","","10","5","8")
$array3 = @("売上",$empty, 2000,5000,300)
$array4 = @("在庫","注文中" ,"少", "",$empty)
Excelでも行と列を入れ替えることは可能ですが、同じ先頭セルを起点にすることが出来ないので、ならば最初のテキストの段階で入れ替えを実行すればと思い質問しました。
powershellでのExcel操作に関し再挑戦していたのでが現状詳しくpowershellを分かっていませんので悪しからず。
様々な提案に対し「,,」で試した結果だけしか述べられず申し訳なく思っております。
それなら、項目数がそうそう変わることはないでしょうから、#5の式がいいのでは、
Offline
1次元配列をpowershellのwhileを使いループでExcelには
こんな集計結果で得たテキストデータを
品名,いちご,みかん,バナナ,リンゴ,梨
数量,,20,20,10,14
金額,3970,760,2640,1760,4720
備考,p,s,p,s,s
在庫,注文中 ,少,, 多,少
*powershell文に組み込むための変数の計算式
Let([e = While (
[
t = Pow::a1 ;
nc = PatternCount ( GetValue ( t ; 1 ) ; "," ) + 1 ;
nr = ValueCount ( t ) ;
t = Substitute( t ; "," ; ¶ ) ;
i = 0 ;
re = ""
] ;
i < nc * nr ;
[
j = Mod ( i ; nr ) * nc + Div ( i ; nr ) + 1 ;
re = re & GetValue ( t ; j ) & Case ( i + 1 = nc * nr ; "" ; Mod ( i + 1 ; nr ) ; "," ; ¶ );
i = i + 1
] ;
re
);
a = Substitute ( e ;"," ; "\",\"" )];
While ( [aa = "";i = 0 ] ; i < ValueCount ( a); [ aa=aa&"$array" & i+1 & " = @(\"" & GetValue ( a ; i+1 ) & "\");";i = i + 1 ]; aa ))
↓
*計算結果
$array1 = @("品名","数量","金額","備考","在庫");$array2 = @("いちご","","3970","p","注文中 ");$array3 = @("みかん","20","760","s","少");$array4 = @("バナナ","20","2640","p","");$array5 = @("リンゴ","10","1760","s"," 多");$array6 = @("梨","14","4720","s","少");
Quote (Evaluate ())でpowershellコードを完成させeventを送信スクリプトでpowershellをを実行させExcelの任意のセル範囲に書き出すのに問題は生じていません。
なお
>項目数がそうそう変わることはないでしょうから、#5の式がいいのでは、
と勧められましたが行列の数は参考例のため少ないだけですので汎用式の方を使用させていただいています。
追記
#23で使ったダブルクォートで囲む下記の方法では、文字数が増えるので1行の文字数が「コマンド プロンプトで使用できる文字列の最大長は 8191 文字」の最大文字数制限の考えると配置方法によっては多少の問題があるかも
$array4 = @("バナナ","20","2640","p","");
過去の質問の際注意を受けていたのを思い出して気になったもので・・・数字の2文字数は2桁分に当たるから
文字数が気になるならpowershellにはファイル名を渡して、そっちで直接CSVからデータを得るようにすればいいのでは。
Excelにデータをいれるなら、エクスポートしたままのデータを入れて、Excelの方で編集すれば簡単そうですが。
コピペするだけで貼り付け時にオプションで指定できるそうです。
https://www.pc-koubou.jp/magazine/50678
今更ですが、項目名が縦に並ぶデータってすごく違和感がありますが...
[ Generated in 0.074 seconds, 7 queries executed - Memory usage: 582.73 KiB (Peak: 619.64 KiB) ]