質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

6回答

5552閲覧

エクセル VBA 1つのセルの値を分けて、逆並びで列に配置

marutoki

総合スコア16

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2017/01/16 04:44

編集2017/01/16 15:04

教えてください。

F列2行目から例えば、
43x43x5(×は大文字のx(エックス)で代用してます。)
というサイズ「縦x横x高さ」が入力されています。
これを数値ごとに分割して、
T列(高さ)、U列(横)、V列(縦)としたいです。

エクセルの基本設定で「データ」⇒「区切り位置」で分割はできるのですが、
これを逆向きに配置するというのはやはりマクロでないと不可能でしょうか?

出来れば数値はコピー貼り付けしたいので、関数ではなく
エクセルの書式設定や基本設定、もしくはマクロで良い方法がないでしょうか?

【追記】
rrryutaro様の教えによりなんとか下記コードで動作しました。
ただ、あくまで「縦x横x高さ」すべてそろっている場合で、
高さのないもの(「縦x横」)があると、当然ですが、
「インデックスが有効範囲にありません。」
となります。
Splitで抽出したvの値は0,1,2ですよね?
これを0,1の時、0,1,2の時で処理を分ける必要がある。
例えば v = Split(r, "x")の後に
IF文を入れて、
V=0,1のみ then
Cells(i, "V") = v(LBound(v))
Cells(i, "U") = v(LBound(v) + 1)
else
Cells(i, "V") = v(LBound(v))
Cells(i, "U") = v(LBound(v) + 1)
Cells(i, "T") = v(LBound(v) + 2)

う~ん、
このあたりの書き方がなんとも分かりません・・・。

Sub 並び替え() Dim myRng As Range ' F列のデータ範囲 Dim r As Range ' ループ作業用 Dim v As Variant Dim i As Long ' データ範囲をセット Set myRng = Range(Cells(5, "F"), Cells(Rows.Count, "F").End(xlUp)) 'T列(高さ)、U列(横)、V列(縦)としたい ' ループ処理 i = 5 For Each r In myRng v = Split(r, "x") Cells(i, "V") = v(LBound(v)) Cells(i, "U") = v(LBound(v) + 1) Cells(i, "T") = v(LBound(v) + 2) i = i + 1 Next End Sub ①2行目から対象範囲の最終行までループ処理 (行ループここから) ②ループ処理行のF列から値を取得 ③取得した値を"x"で分割(Split関数を利用) ⇒配列 (0): 縦 配列 (1): 横 配列 (2): 高さ が格納される ④配列0~2の値を列V~Tに出力する ⇒Cells(ループ行, "V") = 配列(0) Cells(ループ行, "U") = 配列(1) Cells(ループ行, "T") = 配列(2) (行ループここまで) ⑤対象範囲の最終行までループ処理

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rrryutaro

2017/01/16 06:05 編集

「関数ではなく」の一言が皆さん結構引っかかって、回答を悩んでいる部分があるかと思います。これが具体的に何を指しているのかが一言あると回答の助けになります。 例えば、Excelでの分割した結果にワークシート関数を使用した場合、それをコピーして、それをまたExcelに貼り付けた場合、ワークシート関数をコピーしてしまうことの懸念でしたら、jawaさんの提示する別案①の方法で解決できます。
marutoki

2017/01/16 07:25

ありがとうございます。「関数ではなく」の部分は数値としてコピーしたい、しかも条件付き貼り付けをせずに、という思いからです。jawaさんの別案①については、 一番確実かつ簡単ですが、コピーするのが第三者(もっと初心者)であるため注釈などが必要となりシステムとして使いづらいものになってしまいます。
rrryutaro

2017/01/16 07:34

はい。状況がよくわかりました。回答ありがとうございます。
guest

回答6

0

ベストアンサー

もうほぼ自力で答えを出されていらっしゃると思いますが、やりたいことのもう一歩のところで手が止まってしまうってありますよね。
次のような形でいけると思います。

VBScript

1Sub 並び替え() 2Dim myRng As Range ' F列のデータ範囲 3Dim r As Range ' ループ作業用 4Dim v As Variant 5Dim i As Long 6 ' データ範囲をセット 7 Set myRng = Range(Cells(5, "F"), Cells(Rows.Count, "F").End(xlUp)) 8 9 'T列(高さ)、U列(横)、V列(縦)としたい 10 ' ループ処理 11 i = 5 12 For Each r In myRng 13 v = Split(r, "x") 14 If UBound(v) < 2 Then 15 Cells(i, "V") = v(LBound(v)) 16 Cells(i, "U") = v(LBound(v) + 1) 17 Else 18 Cells(i, "V") = v(LBound(v)) 19 Cells(i, "U") = v(LBound(v) + 1) 20 Cells(i, "T") = v(LBound(v) + 2) 21 End If 22 i = i + 1 23 Next 24 25End Sub

配列が0,1の時と0,1,2の時とがあることが分かっていますので、配列の上限を返すUBoundを使うことで判断できます。
LBoundは下限を返す関数です。
Boundは境界。
LBoundLはたぶんLowerで下を示すのでLower Boundで下限(下界?)。
UBoundUはたぶんUpperで上を示すのでUpper Boundで上限(上界?)。
という意味合いになるかと思います。

#追記:ついでなので、こんな書き方もありますという例です。
まず、Excelのシートは次のようにしています。
イメージ説明

コードは次の通りです。

VBScript

1Sub Hoge() 2On Error GoTo Err 3Dim targetCells As Range 4Dim readCell As Range 5Dim writeCell As Range 6Dim readArray As Variant 7Dim writeArray As Variant 8Dim i As Long, j As Long 9 10 Set targetCells = Range("F2", "F" & ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).Row) 11 Set writeCell = Range("T2") 12 13 Application.ScreenUpdating = False 14 For Each readCell In targetCells 15 ReDim writeArray(2) 16 readArray = Split(readCell, "x") 17 j = 2 18 For i = 0 To UBound(readArray) 19 writeArray(j) = readArray(i) 20 j = j - 1 21 Next 22 Range(writeCell, writeCell.Offset(, 2)) = writeArray 23 Set writeCell = writeCell.Offset(1) 24 Next 25Err: 26 Application.ScreenUpdating = True 27End Sub

実行結果は次のようになります。
イメージ説明

逆にわかりづらくて混乱させるかもしれませんが、いくつか知って欲しいポイントがありますが、そんな方法もあるんだ程度に思ってください。

まず、セルの範囲を知る方法は色々とありますが、UsedRangeがあります。
この例では、UsedRangeから、使われている最後の行の行番号を取得しています。
ただし、この方法はF列以外の列でF列以上のデータがあると正しい範囲を得られませんので、元々の方法である、.End(xlUp)で最後に入力のあるセルを得る方がよいかもしれません。

ScreenUpdatingは、VBAを使い出した際に、大量データで処理が遅い時にかならずといっていいほど使う手段です。
ScreenUpdatingFalseだと画面の描画を一切更新しなくなります。Trueにすることで、通常通り更新されるようになります。つまり、セルへの書き込みなどを描画しないので速くなりますが、Trueにし忘れると、何も反応が無くなったようになり、戻し方が分からなければExcelを終了せざる終えなくなりますので、注意が必要です。

このため、On Error Goto Errとして、エラーが発生した場合、Err:ラベルへジャンプするようにして、必ずScreenUpdatingをTrueにするようにしています。

後は配列は0 to 2固定と考えて、書き込み用の配列を作成し、後ろから値を入れて、セル範囲に配列で書き込んでいます。

セルの操作は相対参照するようにしています。まず最初にSet writeCell = Range("T2")として書き込みするセルの開始点を設定します。

値を貼り付ける時は、T~Vとなるように、.Offset(, 2)として、自身から2列離れたセルを参照させています。
最後に、.Offset(1)としてひとつしたのセルへと設定しています。

この辺のセル操作はそれぞれに好みのやり方もあるかと思いますが、Excel VBAでもっとも重要といってもよいくらいRangeオブジェクトは重要だと自分は考えています。

以上

投稿2017/01/17 00:24

編集2017/01/17 00:55
rrryutaro

総合スコア146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marutoki

2017/01/17 01:59

質問に対する解答だけでなく、コードの意味や考え方まで丁寧に教えていただいて感謝感激です! サンプルコードも非常に勉強になります。 よく見ると、「40R」とかもあり、私のマクロでは動きませんでした(-_-;) また、IFで増やせばよいのですが・・・ しかし、サンプルコードなら.splitで取得した値が0~2まで対応できますね。 .rangeも大切ですが、For~Next中の.offset(1)で行数を増やしていくという仕組みがようやく分かりました。 入れ子やReDimとか、まだまだ自分では考え付きませんので経験を積んでいこうと思います。 ありがとうございました。
rrryutaro

2017/01/17 03:37

自分もteratailをはじめたばかりということもあり、どこまで質問に答えられるかという練習をしているようなところもありますので、参考になれば何よりです。 頑張ってください!
guest

0

関数を自作してはどうでしょうか。

Function RevStr(orgStr As String) myAr = Split(orgStr, "x") RevStr = myAr(2) & "x" & myAr(1) & "x" & myAr(0) End Function

ワークシート上で一般の関数と同様、セルに"=RevStr(A1)"という感じで使用します。

投稿2017/01/16 05:16

ynakano

総合スコア1894

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ynakano

2017/01/16 05:25

「関数ではなく」とあったのですね… お気に召さなければ無視していただいて結構ですが、関数でも「数値はコピー貼り付けしたい」要望はかなえられると思うのですがいかがでしょうか。
rrryutaro

2017/01/16 05:27

ynakanoさんの方法が、マクロを使った場合のシンプルな方法のひとつでいいですね。 でも、折角ならば、引数を1つ増やして、配列の何番目を返すかのインデックスにしてしまえば、それぞれ、T列、U列、V列に直接結果を返せるのでより便利だと感じました。 さらについでにデリミタも指定すればさらに汎用的になるかと思います。 自分も関数を用意してみようかと思いましたが、ynakanoさんの方法でまずは十分なので、こちらにコメントさせていただきました。
ynakano

2017/01/16 05:39

正直、何に・どのように使われるのかが不明な(質問文以上の事が読み取れない)状況で必要以上に汎用性を追い求める事が良いこととは思わないです。 利用するにあたり複雑性が増し、処理速度も(気にならないかもしれませんが)確実に遅くなるはずです。 作る側としては汎用性の高いものをと思うのはよく分かるのですが、やりたい事とのバランスで最もシンプルな実装をする方がよいと考えています。
rrryutaro

2017/01/16 05:44

そのような方針だったのですね。おっしゃる意味よくわかります。 特にこうした場では質問者に合わせることを考えると、余計な情報があることで理解を妨げてしまう可能性もありますので、まずはシンプルな回答を提示して、そこからリアクションをもらう方がよいですよね。
marutoki

2017/01/16 06:39

すみません、高尚なコメントをいただいて恐縮なのですが、 初心者に毛が生えたようなレベルなので使い方をもう少し教えてください。 あと回答0の方にも書いていますが、高さのない商品もあります・・・。 たぶん使い方も違うでしょうが、 T列に =RevStr(F1) といれるとそのままセルに「45x45x5」と入ります。 ただ、今回作成する表は値をコピーして貼り付けるのが、さらに初心者の方で、条件付き貼り付けで値のみとか、難しいので数値として取り出せるマクロにしたかった次第です。 余談ですが、質問する際、どこまで情報を提供するかは悩むところで、 情報が多すぎると、本来質問したい部分が埋もれてなかなか思っていた回答が得られない場合が多いです。 もちろん初心者としては汎用性があって、理解し易くて、応用がしやすい というのが一番なんですが。 また、長々と手順やマクロを書いていただたあとで、いや~ちょっと違うんだよな~。 となると、申し訳なくて申し訳なくて・・・ なので、rrryutaroさんも回答されているように最初はシンプルな回答でいただけると助かります。こちらも核となる部分だけを質問し、芋づる式にすり合わせていきたいです。
ynakano

2017/01/16 06:46

使い方は合ってますよ。 簡単にですが自分でも動作確認してます。元の文字列が全て表示されているのを見ると、区切り文字が一致しないのでしょうか… 「高さがない」ケースについては、UBound関数を使ってmyAr配列の要素数を調べ、その数によって処理を分ければよいかと思います。 縦横高さ全てあれば配列要素数は3でしょうし、縦横だけなら2になるはずですので。
guest

0

マクロで作るなら

マクロで処理するならSplit関数で配列に格納し、任意の列に出力すれば目的の結果が得られると思います。
※今回はご自身で作成されたコードの提示がないため、具体的なサンプルコードの公開は控えさせていただきますm(__)m

処理手順としては

①2行目から対象範囲の最終行までループ処理 (行ループここから) ②ループ処理行のF列から値を取得 ③取得した値を"x"で分割(Split関数を利用) ⇒配列(0):縦 配列(1):横 配列(2):高さ が格納される ④配列0~2の値を列V~Tに出力する ⇒Cells(ループ行,"V")=配列(0) Cells(ループ行,"U")=配列(1) Cells(ループ行,"T")=配列(2) (行ループここまで) ⑤対象範囲の最終行までループ処理

のような流れになると思います。

別案①

ちなみに、コピーしたいからExcel関数は避けたい、というのはよくわかります。
関数で簡単に実現できるけど、値で作りたい。でもいちいちマクロを作るのは面倒だ…という場合、関数で目的の結果を作成した後に対象範囲全体を「コピー」⇒同じ範囲に「値の貼り付け」とすることで最終的に値で作成することもできます。

別案②

今回の場合、
>「データ」⇒「区切り位置」で分割はできる
とのことですので、これで作成したシートの列を並べ替えるマクロを作成する、という方法もあります。

別案③

自分ならどうするかを考えた時、Excelに持ってくる前に加工してしまう方法を取りそうな気がします。

正規表現置換を使えるテキストエディタで事前に加工しておくと、Excelでもできるけど多少面倒なことが意外と簡単にできてしまったりします。

今回の場合、
^(.+)x(.+)x(.+)$

\3\t\2\t\1
に置き換える正規表現置換を行うと、そのままエクセルに貼り付ける形が用意できます。

ExcelでもVBAでもないアドバイスになってしまいますが、今回のニーズにマッチしそうだったのでご紹介してみました。

参考になれば幸いです。

追記:サンプルコード
サンプル公開を控えたのは丸投げ対策でしたが、marutokiさんからは学習意欲がみられるのでサンプルコードを提供させていただきます。

Sub test() Dim sht As Worksheet '対象シート Set sht = ActiveSheet '今回はとりあえずアクティブシートを対象シートに設定 Dim iRow As Integer '行ループ Dim iIdx As Integer '配列から値を取得する Dim strVal As String 'F列セル値 Dim aryVal() As String '分割結果 '2行目からF列最終行までループ処理 For iRow = 2 To sht.Cells(Rows.Count, "F").End(xlUp).Row 'F列から値を取得 strVal = sht.Cells(iRow, "F").Value '取得した値を"x"で分割 aryVal = Split(strVal, "x") '縦・横・高さのループ処理(配列の個数だけループ処理) For iIdx = 0 To UBound(aryVal) - 1 If iIdx > 2 Then Exit For '3回以上はループしない。(1x2x3x4でも3まで処理) '1回目:V列(22列)、2回目U列(21列)、3回目T列(20列)に値を出力 sht.Cells(iRow, 22 - iIdx).Value = aryVal(iIdx) Next iIdx Next iRow End Sub

投稿2017/01/16 05:54

編集2017/01/17 00:20
jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marutoki

2017/01/16 07:16

ありがとうございます。 とりあえず、本案が稼働するよう勉強したいと思います。 別案①については、 一番確実かつ簡単ですが、コピーするのが第三者(もっと初心者)であるため注釈などが必要となりシステムとして使いづらいものになってしまいます。 別案②については、 これが一番私の身の丈に合っている方法だと思います。 ただ無駄な列やシートを使わずやりたいという思いは理解いただけたらと思います。 別案③については、 勉強不足で初めて聞きました。 正規表現置換ですか、勉強します。
jawa

2017/01/16 07:52

第三者がコピー作業を行うのであれば、別案③も難しそうですね(^-^; サンプル公開を控えたのは丸投げ対策でしたが、marutokiさんからは理解しようという意欲がみられますのでサンプルコードを提供させていただきます。 わかりにくいところなどあればご質問ください。
marutoki

2017/01/16 09:00

ありがとうございます。 一応、本案でいただいたアドバイスを元にやってみましたが、なかなか・・・ (質問に追記しています) もちろん、できました!あざ~す!で終わるつもりはありません。 正直現場作業もあり、なかなかマクロに集中できる環境になく、学習速度はかなり遅いです(笑) ですが、マクロを知れば知るほど私のような小規模事業者にとって必須だなと実感しております。 質問する以上、最低限の知識は身に付けたく、VBAエキスパート ベーシック合格に向け勉強中です。 イメージは沸くのに形にできないもどかしい現状ですので今しばらくお力添えをいただければ幸いです。
jawa

2017/01/17 00:36

追記拝見しました。 Splitした時に要素が少ない場合のことを懸念されているようですね。 私が紹介したサンプルではそこらへんも考慮されていますので、ちょっと解説しますね。 ポイント① --- まずSplit関数ですが、 「1x2x3」を"x"で分割すると3つの要素に分解され、 「1x2」を分解すると2つの要素に分解されます。 この要素の数を取得するのがUBoundという関数です。 UBound関数を使うと、「1x2x3」を分解したときには3、「1x2」を分解したときには2という値を返してくれます。 ポイント② --- 私が紹介したサンプルコードでUBound関数で取得した要素数をどう使っているかというと ``` For iIdx = 0 To UBound(aryVal) - 1 ``` という具合にループ処理のMax値として利用しています。 配列の要素数応じてループ回数を増減させているということです。 ここで配列の要素数-1としている理由は、インデックス値として利用するためです。 「1x2x3」の要素数Uboound(aryVal)は3ですが、配列から値を取り出すときにはaryVal(0)~aryVal(2)で取り出しますので、0~2のループとなるように3-1としているわけです。 ループ1周目は縦の要素の値を取得するので、V列(22列目)に出力します。 ループ2周目は横の要素の値を取得するので、U列(21列目)に出力します。 ループ3周目は高さの要素の値を取得するので、T列(20列目)に出力します。 これを実現しているのが ``` '1回目:V列(22列)、2回目U列(21列)、3回目T列(20列)に値を出力 sht.Cells(iRow, 22 - iIdx).Value = aryVal(iIdx) ``` の部分です。 当然ですが要素数が2の場合はループが2周しか回りませんので、T列は出力されません。 この仕組みが理解できればmarutokiさん作成のコードにも応用できると思います。 頑張ってみてください。
marutoki

2017/01/17 02:13

ありがとうございます!すみません、先に読んでいたrrryutaro様をBAに選ばさせてもらいましたが、 jawa様の回答も同等に非常に分かりやすく助かりました! なにせサイズは手入力ですから何が起こるか分かりません。 .Splitで取得する数を If iIdx > 2 Then Exit For で制限するとエラーも出ず助かります。 For~Nextの入れ子で対応はとても応用が利きますね。 セルへの転記の仕方もいろいろあるのだと勉強になりました! また分からないことがあれば質問させてください。
guest

0

関数でも可能ですが、関数以外をご希望とのことで、サンプルをご紹介します。

※コメントを受けて、一部修正しました。
修正点1.xの大文字小文字不問(混在も可)
修正点2.パターンにマッチしない場合、配列に空欄をセット

※他の方が回答されているように、Split関数で分割する方法のほうが、わかりやすいかもしれません。

※高さが無い場合について、このマクロは本質的に対応できていません。従って実務においては、他の方が
提示されたSplit関数を使用されるほうがよいとおもいます。ただし正規表現も、覚えておけば絶対に
損はしないと思いますので、この機会に是非挑戦してみてください。

VBA

1Sub Sample() 2 3 Dim myRng As Range ' F列のデータ範囲 4 Dim r As Range ' ループ作業用 5 Dim myReg As Object ' 正規表現 6 Dim mc As Object ' Match Case 7 Dim buf As Variant ' データ格納用配列 8 Dim i As Long ' ループカウント用 9 Dim j As Integer ' ループカウント用 10 11' 正規表現使用準備 12 13 Set myReg = CreateObject("VBScript.RegExp") 14 15' データ範囲をセット 16 17 Set myRng = Range(Cells(2, "F"), Cells(Rows.Count, "F").End(xlUp)) 18 19' データ範囲から、配列を再定義 20 21 ReDim buf(1 To myRng.Count, 1 To 3) 22 23' パターン定義 24' ※1文字以上連続する数字の三つの塊が、「x」で繋がっているもの。 25' ※「\d」は、数字を表しています。「+」は、直前の文字が1回以上連続していることを意味しています。 26' ※従って、\d+は、1回以上連続する数字をあらわすことになります。 27' ※これを()で括ることによって、のちほど取り出すことができるようになります。 28 29 myReg.Pattern = "(\d+)x(\d+)x(\d+)" 30 31' ループ処理 32 33 i = 1 34 35 For Each r In myRng 36 37  ' Executeメソッドを用いて、対象となる文字列がパターンに一致した場合、それを 38  ' Matchコレクションに格納します。要は、後で使えるようにしています。 39  ' 半角数字も存在するとのことで、StrConv(r, vbLowerCase + vbNarrow)としました。 40  ' mc(0)となっているのは、パターンに合うものが各文字列に一つしかないためです。 41  ' 一つの文字列に、パターンに合うものが複数ある場合は、mc(1),mc(2)と続きます。 42  ' パターンにマッチした場合、一つ目の()がSubmatches(0)となります。後は同じ要領です。 43 44 Set mc = myReg.Execute(StrConv(r, vbLowerCase + vbNarrow)) 45 If myReg.test(StrConv(r, vbLowerCase + vbNarrow)) Then 46 buf(i, 1) = mc(0).submatches(2) 47 buf(i, 2) = mc(0).submatches(1) 48 buf(i, 3) = mc(0).submatches(0) 49 Else 50 For j = 1 To 3 51 buf(i, j) = "" 52 Next j 53 End If 54 i = i + 1 55 56 Next 57 58' データ貼り付け 59 60 Cells(2, "T").Resize(i - 1, 3) = buf 61 62 Set myRng = Nothing 63 Set myReg = Nothing 64 Set mc = Nothing 65 66End Sub

参考になれば、幸いです。

投稿2017/01/16 05:20

編集2017/01/16 23:27
Wolf

総合スコア38

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marutoki

2017/01/16 06:13

超初心者ですので、理解がぎりぎりのマクロですが・・・ すみません。 大前提を崩してしまうのですが、高さがない商品もありまして・・・ Cells(2, "T").Resize(i - 1, 3) = buf   でエラーになってしまいます。 myReg.Pattern = "(\d+)X(\d+)X(\d+)" のXは様々な制約上x(全角小文字のエックス)に変えましたが問題ないでしょうか。
Wolf

2017/01/16 07:21

回答を一部修正しましたので、ご参考ください。
marutoki

2017/01/16 15:40

修正いただきありがとうございます。 かなり上級なため、できましたとしか言えないのがつらいですが。 また大前提の話ですが、無事動作完了するのですが、 全角数字では反映されないのですねorz 全角で質問して満足してましたがいろいろな制約で数値も全て全角になっています。 全角数字を半角にするマクロを調べて勉強してから利用させていただきます。
Wolf

2017/01/16 23:30

「全角を半角に」ということで、マクロを修正しました。 また、コメントも少し追記しました。 私も専門は情報系ではなく、Net上で受けた数々のご指南に育てていただきました。 従って、コメントやマクロの内容に誤りなどありましたら、ご容赦くださいm(_ _)m
guest

0

marutokiさん、はじめまして。
もっとも簡単な方法は単純に、作業用に別のセルにその分割した値を貼り付けて、それを参照する形だと思います。

次の例は、X Y Zのセルに「データ」⇒「区切り位置」で分割 した結果。
それをT列はZ列を、U列はY列を、V列はX列を参照することで、逆ならびにしています。
イメージ説明

これではあまり望みの方法ではないでしょうか?

分割結果をX Y Zでなくとも、もっと離れたセルにしても良いですし、隠しても良いですし、別シートにしてもよいです。
Excelでは、ワークシート関数などをいっぺんに呼ばなくても、途中途中の結果を作業用のセルに出力して、段階的に利用する手は最もよく使われている手法だと思います。

ただ、マクロを使ってみようという気持ちがありましたら、色々と便利になりますので、別途回答したいと思います。

投稿2017/01/16 05:18

rrryutaro

総合スコア146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marutoki

2017/01/16 07:21

ありがとうございます。 一番身の丈に合った方法です。 ただ、もっと初心者の第三者がコピペして使うものなのでT~V列は数値として転記したいです。 また、他の方の回答にも書きましたが、高さのない商品もあります。
rrryutaro

2017/01/16 07:33

はい。他の回答者へのコメントで状況が理解できました。 状況的には、ynakanoさんの反転した結果を分割してT~V列に転記すれば、第三者の方がコピペで困らないかと思います。 あるいは、marutokiさん自身が提供する際に、形式を選択して貼り付けしなおす手もあるかもとは思いますが、手間がかかりますよね。 一番いいのは、Subプロシージャを呼べば一発で、高さが無い場合も考慮してT~V列に反転した結果が貼りつくことだと思いますが、少しマクロが難しくなると思います。
guest

0

marutokiさん! splitの指定がmyRngになっていますよ!
rでなくてはなりません。
また結果の受け取りは別途Variant型の変数を用意してください。

念のため簡単に解説します。
例えば、F列が次のようになっていた場合

- F列 2 1x2x3 3 2x3 4 3x4x5

myRngは次のような配列になっています。
F2のセル, F3のセル, F4のセル
For Each r In myRngはmyRngの配列を1つずつ取り出して、rに格納します。

次のようにする必要があります。

Dim v As Variant : v = Split(r, "x")

ちなみに、デバッグ機能は利用されていますでしょうか?
別件での回答になりますが、次の質問での回答でデバッグの使い方を少し説明してますので参考にしていただければと思います。
VBA - VBA 配列(62043)|teratail

投稿2017/01/16 08:30

編集2017/01/16 08:35
rrryutaro

総合スコア146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marutoki

2017/01/16 14:49

分かりやすい解説ありがとうございます。 r In myRngとした時点でrに格納されている、言われれば確かにとは思うのですが・・・、デバック機能もF8で進めるとかなんとなくでしか理解できていません。これが先へ進めない原因でしょうね・・・。 エラーがあるたびやろうとしていますが、すでにエラーの事で頭がいっぱいになるため、まずは正常動作品でどういう動きをしているかを確認するツールとして使ってみながらやった方が理解しやすいかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問