「これはヤバかったな」という遅刻エピソード

お世話になっております。

例えばA1セルの4桁の数字で出来る組み合わせの4桁の数字をB列~列記するようにしたいのですが。
A2,A3と下のセルにも4桁の数字が入っているので、式のコピーでB列~に表記されるようにしたのですが関数が思いつきませんので宜しくお願いします。

質問者からの補足コメント

  • あっ、すいません。
    A1に1234と入っていたら、B1には1243、C1に1324・・・というようにA1に入っている4つの数字で構成される4桁の数字全てを列記したいのです。
    A1の数字は重複もありですので、1111の場合はB列以降に1111が並ぶ感じでもOKです。

    No.1の回答に寄せられた補足コメントです。 補足日時:2024/08/05 08:31
  • 条件抜けがあり申し訳ありません。

    1.0は存在します。
    数字なので123でOKですが、4桁あった方が簡単なら文字列にします。(最後は数字に戻します)

    2.重複した数字は不要です。
    当方のレベルではVBAで重複確認が必要かと思い機械的に処理して同じ数字が24個並んでもOKとしました。
    重複許容と削除で どちらが簡単かは想像できませんので簡単な方で結構です。

    3.実際の表はA1に4桁の数字が入っています。
    B列以降に24個の組み合わせを出力出来れば一番ありがたいのですが、例えばA列をAA列にコピーして、=LEFT関数でA1~D1に1文字ずつ分割することは出来ますのでどちらでも結構です。

    今更ですが行列逆にして、24個の合成数字を各列の下方向に表記してもOKですのでやり易い方で結構です。
    VBAが良く分かりませんの縦と横でやり易い、やりにくいが有ればの話です。

    No.4の回答に寄せられた補足コメントです。 補足日時:2024/08/05 14:26

A 回答 (5件)

A1に1234 だったら、B1に1 B2に2 ...


という感じにしたいということですか?
今のところ、完成形がよく分かりません。
この回答への補足あり
    • good
    • 0

文字列にすればいいじゃない。



 =”0000”&A1

これで3桁でも2桁でも問答無用で4桁以上の文字列になります。
そしてこれを右から4文字切り取って、そこから1文字ずつ拾えばいい。
RIGHT関数とMID関数の組み合わせです。
切り取る位置はCOLUMN関数を使って決めてやればいい
 =COLUNM(A1)
なら「1」が返ってくる。
式を横方向にフィルコピーして
 =COLUNM(B1)
になれば「2」が返る。

ということで、ちょっと考えてみてください。
試行錯誤することで、自分で数式を組み立てる訓練になります。
がんばれ。
    • good
    • 0
この回答へのお礼

早々のご回答ありがとうございます。
最初は
A1の1234を各セルに1桁ずつ抜いて(ここまでは出来ます)これを順列組み合わせで16個?埋めようとしたのですが途中で順列が分からなくなって自信が無くなって・・・
で分かりやすい解が無いかと質問させて頂きました。

お礼日時:2024/08/05 08:40

なるほど、そういうことですか。



4×3×2×1=24の列が必要になるわけですね。
(16個じゃねえぞ)

  1 1234
  2 1243
  3 1324
  4 1342
  5 1423
  6 1432
  7 2134
  8 2143
  9 2314
 10 2341
 11 2413
 12 2431
 13 3124
 14 3142
 15 3214
 16 3241
 17 3412
 18 3421
 19 4123
 20 4132
 21 4213
 22 4231
 23 4312
 24 4321

を表示させたいって事だね。

自分なら面倒なんで、この表を【参照】させる。
このアルゴリズムを数式で示すとスゲー面倒で冗長になるんだ。

【参照】方法は、
 INDEX関数に表を配列としてCOLUMN関数で得た値で選択するとか、
 COLUMN関数で得た値をINDIRECT関数に入れて参照範囲にするとか、
 COLUMN関数で得た値をOFFSET関数に入れて参照範囲にするとか、
やり方はいろいろある。
で、各桁の数字を参照するセルの値の桁として使う。

 1234→ 左から1文字目 & 左から2文字目 & 左から3文字目 左から4文字目
 4321→ 左から4文字目 & 左から1文字目 & 左から2文字目 左から1文字目
のようになるよう、

=MID(A1, MID(表参照+0 ,1,1)+0,1) &
 MID(A1, MID(表参照+0 ,2,1)+0,1) &
 MID(A1, MID(表参照+0 ,3,1)+0,1) &
 MID(A1, MID(表参照+0 ,4,1)+0,1)

こんな感じになります。
(分かりやすいように改行しています)

=MID(RIGHT("0000"&A1,4), MID(表参照+0 ,1,1)+0,1) &
 MID(RIGHT("0000"&A1,4), MID(表参照+0 ,2,1)+0,1) &
 MID(RIGHT("0000"&A1,4), MID(表参照+0 ,3,1)+0,1) &
 MID(RIGHT("0000"&A1,4), MID(表参照+0 ,4,1)+0,1)
必ず4桁の数字が入力されるとは限らないから、こんな感じにした方が良いのかな。

 MID(表参照+0 ,1,1)+0
などの「+0」は文字列を数値に変換するための横着です。
本来は
 N(MID(N(表参照) ,1,1))
のようにすべき。

’表参照’ の部分は上記の ’【参照】方法は、’ を参考にしても良いし、質問者さん独自のアルゴリズムでも良い。


まあ、こんだけでもスゲー面倒な数式になるので、24種類のパターンを書き出すアルゴリズムを含めると意味不明なものになることは理解してもらえると思います。

・・・

なお、「1111」がずらっと並ぶという事ですので、重複を省略するアルゴリズムは考えていません。
A1セルに
 1123
と入力されていた場合、1123 1132 1213 1231 2113 2131 2311 3112 3121 3211 などは重複表示されます。
    • good
    • 0
この回答へのお礼

失礼しました。
4X4で16通りと思いましたが順列式4P4で24通りでした。

成る程、と言うかやはりかなり面倒なのですね、と言う感じです。
実際の表には、A2以下 下に数十の4桁の数字が入っているので一覧表は無理だと思い、最初に4桁の数字を、A1に1、B12に2、C1に3、D1に4として、E列に=A1&B1&C1&D1、F列にA1&B1&D1&C1と言うように24個作れば下にコピーで行けると思ったのですが6個位作ったところでGIVE UPしてしまった次第。

A1~D1までの1桁の数字(文字)をランダムに組み合わせて、重複しない24個を抽出するような関数orVBAが無いかと期待したのですが。

お礼日時:2024/08/05 10:07

>A1~D1までの1桁の数字(文字)をランダムに組み合わせて、重複しない24個を抽出するような関数orVBAが無いかと期待したのですが。



VBAでなら提供可能です。その際の確認事項です。
下記の件、補足をお願いします。

1.4つの数字の中に0がある場合がありますか。
もし、0があると、"0123"と表示すると123と表示されてしまいます。
その為、事前に各セルの書式設定を文字列にしておく必要があります。

2.重複があった場合でも、24ケースを出力しますか。
(例元の数字が1111なら1111を24個出力する)
それとも、1回だけ出力すれば良いのでしょうか。

3.元の数字はA1に4文字あり、B列以降に24個の組み合わせを出力するのでしょうか。
それとも、A1,B1,C1,D1に1文字づつあり、D列以降に24個の組み合わせを出力するのでしょうか。
この回答への補足あり
    • good
    • 0

VBAになります。


A列~Y列の書式設定は文字列の前提です。
(A1に0123のように入力します。123はNGです)
重複した組み合わせは1度だけ出力されます。
以下のマクロを標準モジュールに登録してください。

Option Explicit
Public Sub 組み合わせ()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim maxrow As Long
Dim wrow As Long
Dim wcol As Long
Dim str As String
Dim dicT As Object

Set dicT = CreateObject("Scripting.Dictionary")
maxrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
For wrow = 1 To maxrow
str = ws.Cells(wrow, 1).Value
ws.Cells(wrow, 2).Resize(1, 24).Value = ""
wcol = 2
Call combi("", str, ws, wrow, wcol, dicT)
dicT.RemoveAll
Next
End Sub

Private Sub combi(ByVal pstr As String, ByVal str As String, ws As Worksheet, wrow As Long, wcol As Long, dicT As Object)
Dim i As Long
Dim ll As Long
Dim str0 As String
Dim str1 As String
ll = Len(str)
For i = 1 To ll
str0 = pstr & Mid(str, i, 1)
str1 = WorksheetFunction.Replace(str, i, 1, "")
If str1 = "" Then
If dicT.exists(str0) = False Then
ws.Cells(wrow, wcol).Value = str0
wcol = wcol + 1
dicT(str0) = True
End If
Exit Sub
End If
Call combi(str0, str1, ws, wrow, wcol, dicT)
Next
End Sub
    • good
    • 0
この回答へのお礼

早々のご回答ありがとうございました。

早々に表の一部をコピーして実行してみたら一発で期待通りに完動(感動)しました。

こんなに短時間でこのロジックのコードが書けることにもっと感動しました。

お礼日時:2024/08/05 14:58

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報

このQ&Aを見た人がよく見るQ&A