Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 11 Home : Microsoft 365)
1つのセルの値を複数の列に分割したい
投稿日時: 22/12/04 09:22:25
投稿者: yurappy

セルの値を複数の列に分割したい
 
お世話になります。
ネットショップの商品データをダウンロードして、新しいショッピングサイトに移行したいのですが、1つのセルに収まっている値を、複数の列に分割できないかで困っております。
 
行いたいことは、ダウンロードしたCSVファイルのD列に次のような形でデータがあります。
 
 
ダウンロードしたCSVファイルのD列の値
 
    https://ドメイン名/フォルダ名/06687619/997080.jpg https://ドメイン名/フォルダ名/77dr768/867gh547y2.jpg https://ドメイン名/フォルダ名/0ldkre466.gif https://ドメイン名/フォルダ名/si043kf72.jpg
 
 
この様に連続しているD列値を、次のようにD列に続く他の列に分割して収まる様にしたいのです。
またできれば、最後のファイル名のみにしたいのです。
 
 
    D列の値
    https://ドメイン名/フォルダ名/06687619/997080.jpg
    
    E列の値
    https://ドメイン名/フォルダ名/77dr768/867gh547y2.jpg
    
    F列の値
    https://ドメイン名/フォルダ名/0ldkre466.gif
    
    G列の値
    https://ドメイン名/フォルダ名/si043kf72.jpg
    
    H列の値
    
    I列の値
    
    J列の値
    
    K列の値
    
    L列の値
    
    M列の値
    
    
できれば、最後のファイル名のみにしたいのです。    
 
 
    D列の値
    997080.jpg
    
    E列の値
    867gh547y2.jpg
    
    F列の値
    0ldkre466.gif
    
    G列の値
    si043kf72.jpg
    
    H列の値
    
    I列の値
    
    J列の値
    
    K列の値
    
    L列の値
    
    M列の値
    
 
 
移動先の列はD列からM列の10列で、値がない場合は空白のままにしたいです。
区切りになる目安は、 jpg jpeg gif などです。
 
 
 
ネットで探してみましたが、連結する方法は見つかるのですが、分割する方法が無く、マクロやVBAなどまったくわからず困っております。
 
分割する方法か、なにか良い方法などご存知でしたら教えてください。
 
 
よろしくお願いいたします。

回答
投稿日時: 22/12/04 11:24:42
投稿者: WinArrow
投稿者のウェブサイトに移動

VBAを使用しない方法を紹介します。
 
第1ステップ
D列文字列を" "を区切り文字として、分割します。
 「データ」タブの「区切り位置」を使います。
ダイアログの最初の画面で
「カンマやスペースなどの区切り文字によって〜〜」を選択します。
次の画面で「スペース」を選択します。
次の画面はスキップして「完了」
 
そうすると、[http://〜」が右側の列セルに入ります。
4つならば、D、E,F、Gの列です。
 
 
第2ステップ
H列セルに数式を入力します。
=MID(D2,FIND("●",SUBSTITUTE(D2,"/","●",LEN(D2)-LEN(SUBSTITUTE(D2,"/",""))))+1,100)
 
※●は、元データには、使われていないという前提です。
 
第3ステップ
上の例は2行目ですから、
H2セルを右へ4つ、下へフィルドラグします。
 

回答
投稿日時: 22/12/04 12:00:00
投稿者: 半平太

Microsoft 365なら数式で出来るかも知れない。
  
D列は元ネタなので、E列から右へ自動スピルさせる。
 
E1セル =LET(x,{"/",".jpg",".jpeg",".gif"},y,{".jpg",".jpeg",".gif"},spl,TEXTSPLIT(REDUCE(D1,x,LAMBDA(a,b,SUBSTITUTE(a,b,b&"♪"))),"♪",,TRUE,1),FILTER(spl,spl<>REDUCE(spl,y,LAMBDA(c,d,SUBSTITUTE(c,d,"")))))
  

<結果図>
行 ______________D________  _____E_____ _______F_______ ______G______ ______H______
 1 https://ドメイン名/・・  997080.jpg  867gh547y2.jpg  0ldkre466.gif si043kf72.jpg

投稿日時: 22/12/04 15:56:54
投稿者: yurappy

WinArrowさま
半平太さま
  
お世話になります。
ご親切に、ありがとうございます。
  
  

引用:

D列文字列を" "を区切り文字として、分割します。

 
  
恥ずかしながら、この手順すらわからずにつまずいてます。
試しに、D列だけでCSVファイルで別名保存をして、区切りを指定するなどして開いて見ましたがダメでした。
  
  
引用:

E1セル =LET(x,{"/",".jpg",".jpeg",".gif"},y,{   後略 

 
  
こちらの数式をE2のセルに書いて試してみましたら #CALC! と表示されて、どうもエラーになった様な感じでした。
  
  
せっかく教えていただいたのに、初歩的な事もできずにお恥ずかしいばかりです。
  
A列や後ろにある列にある値の影響かもと消して試してみても同じでした。
  
ご親切に教えていただいたのにすみません。
  
すみませんが、もし他に良い方法がありましたら教えてください。
  
よろしくお願いいたします。

回答
投稿日時: 22/12/04 15:58:58
投稿者: hatena
投稿者のウェブサイトに移動

VBA板なので、VBAの場合のサンプルコード
 

Option Base 1

Public Sub Sample()
    Dim rng As Range
    Set rng = Range("D2", Cells(Rows.Count, "D").End(xlUp).Offset(1))
    Dim ary: ary = rng.Value
    
    Dim i As Long, j As Long, r
    For i = 1 To UBound(ary)
        r = Split(ary(i, 1))
        If UBound(r) >= UBound(ary, 2) Then ReDim Preserve ary(UBound(ary), UBound(r) + 1)
        For j = 0 To UBound(r)
            ary(i, j + 1) = Mid(r(j), InStrRev(r(j), "/") + 1)
        Next
    Next
    rng.Resize(, UBound(ary, 2)).Value = ary
End Sub

回答
投稿日時: 22/12/04 16:37:19
投稿者: simple

VBAについては、すでに回答をいただいていますので、付けたしです。
 
文字の分割と言えば、Splitでしょうか。
速度があまりクリティカルでなければ、一行ごとに実行してもよいかもしれません。

Sub test()
    Dim r As Range
    Dim ary As Variant
    Dim ary2 As Variant
    Dim j As Long
    Dim k As Long

    For j = 1 To Cells(Rows.Count, "D").End(xlUp).Row
        Set r = Cells(j, "D")
        ary = Split(r.Value, " ")
        For k = 0 To UBound(ary)
            ary2 = Split(ary(k), "/")
            ary(k) = ary2(UBound(ary2))
        Next
        r.Offset(, 1).Resize(1, UBound(ary) + 1) = ary
    Next
End Sub

・Split(r.Value, " ")については、指摘がありましたように、
  スペースによる分割の場合、第二引数を省略することもできますが、
  もちろん書いても問題ありません。
・"/"でSplitして、最後の要素を取り出す
            ary2 = Split(ary(k), "/")
            ary(k) = ary2(UBound(ary2))
  という書き方も結構使われることがあります。
     
以下、余談です。
「区切り位置指定ウィザード」は、
文字列の分解について、基本となるワークシート機能です。
余計なことですが、操作が不明であれば、ネットで検索すると色々な記事がありますよ。
下記の動画は、分かりやすいかもしれない。
(もし単に分割するだけなら、この処理をマクロ記録したものが使えます。)
 
c.f. 「区切り位置指定ウィザードを使用して、テキストをさまざまな列に分割する」
https://support.microsoft.com/ja-jp/office/%E5%8C%BA%E5%88%87%E3%82%8A%E4%BD%8D%E7%BD%AE%E6%8C%87%E5%AE%9A%E3%82%A6%E3%82%A3%E3%82%B6%E3%83%BC%E3%83%89%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%92%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E5%88%97%E3%81%AB%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B-30b14928-5550-41f5-97ca-7a3e9c363ed7

回答
投稿日時: 22/12/04 16:40:01
投稿者: 半平太

>E2のセルに書いて
 
E2セルに、なのですか?
すると、対象データはD2セルにあるんですね。
 
E2セルに =MAP(TEXTSPLIT(D2," ",,TRUE),LAMBDA(a,TAKE(TEXTSPLIT(a,"/",,TRUE),,-1)))
 
※最初の数式はボツにしてください。

回答
投稿日時: 22/12/04 16:50:41
投稿者: WinArrow
投稿者のウェブサイトに移動

yurappy さんの引用:

引用:

D列文字列を" "を区切り文字として、分割します。

 
  
恥ずかしながら、この手順すらわからずにつまずいてます。
試しに、D列だけでCSVファイルで別名保存をして、区切りを指定するなどして開いて見ましたがダメでした。

 
D列文字列を" "を区切り文字として、分割します。
は、そのものを操作するものではなく、以下の手順の概要です。
 
1.D列を選択します。
2.「データ」タブの中に「区切り位置」というボタンをクリックします。
 ⇒ダイアログが表示されます。
3.最初の画面( 1/3)
  「カンマやスペースなどの区切り文字によって〜〜」を選択して「次へ」をクリック。
4.次の画面(2/3)
 「スペース」を選択し「次へ」をクリック。
5.次の画面(3/3)は「完了」をクリック
 
  

回答
投稿日時: 22/12/04 17:26:50
投稿者: hatena
投稿者のウェブサイトに移動

半平太さんのMAP関数の式、素晴らしいですね。
 
この式を借りて、スピルするようにしてみました。
 
=MAP(TEXTSPLIT(TEXTJOIN(";",FALSE,D2:D100)," ",";"),LAMBDA(a,IFNA(TAKE(TEXTSPLIT(a,"/",,TRUE),,-1),"")))

回答
投稿日時: 22/12/04 20:04:21
投稿者: WinArrow
投稿者のウェブサイトに移動

VBAのコード例
  
"/"によるSPLITは不要と考えています。

Sub Sample()
Dim MDATA, SDATA, Mx As Long, Sx As Long
Dim DADD As Range, KARI, KX As Long
    
    With ActiveSheet
        Set DADD = .Range(.Range("D2"), .Range("D2").End(xlDown))
        MDATA = DADD.Value
        ReDim SDATA(1 To UBound(MDATA), 1 To 1 + Len(MDATA(1, 1)) - Len(Replace(MDATA(1, 1), " ", "")))
        
        For Mx = LBound(MDATA) To UBound(MDATA)
            KARI = Split(MDATA(Mx, 1), " ")
            ReDim Preserve KARI(1 To UBound(KARI) + 1)
            For KX = LBound(KARI) To UBound(KARI)
                SDATA(Mx, KX) = Mid(KARI(KX), InStrRev(KARI(KX), "/") + 1)
            Next
        Next
        
        DADD.Offset(, 1).Resize(UBound(SDATA), UBound(SDATA, 2)).Value = SDATA
    End With
        
End Sub

投稿日時: 22/12/05 09:10:37
投稿者: yurappy

お世話になります。
 
hatenaさま
simpleさま
 
ご親切にありがとうございます。
 
WinArrowさま
半平太さま
 
引き続きありがとうございます。
 
 
simpleさまのVBAとhatenaさまの式を試したところ、思うように動きました。
ご親切にありがとうございます。
 
何がどうなっているのか、この後勉強してみます。
なぜこんな難しいことができるのか、エクセルの奥深さの勉強になりました。
 
WinArrowさまの区切り分割の手順もありがとうございます。
こんな方法もあるのかと勉強になりました。
 
無理かと思っておりましたが、皆様に助けれらて本当に助かりましした。
ありがとうございました。
 
 
また困った時には、ご相談させてください、
 
たいへん、ありがとうございました。