[[20230123065924]] 『指定文字で分割』(コニャック) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『指定文字で分割』(コニャック)

A列の文字列を指定文字列(含むスペース)で分割してB列以降に抽出するVBAを考えましたが
理想は例1ですが例2のようにうまく処理出来ていません。

どこを変更すれば良いですか 

    |[A]                      |[B]  |[C]  |[D]  |[E]   
 [1]|test1-test2-test3-test4  |test1|test2|test3|test4 
 [2]|test5-test6              |test5|test6|     |      
 [3]|test7-test8-test-9-test10|test7|test8|test9|test10

例2

    |[A]                      |[B]  |[C]  |[D]  |[E]  |[F]  |[G]  
 [1]|test1-test2-test3-test4  |test7|     |     |     |     |     
 [2]|test5-test6              |     |test7|     |     |     |     
 [3]|test7-test8-test-9-test10|     |     |test7|     |     |     
 [4]|                         |     |     |     |test7|     |     
 [5]|                         |     |     |     |     |test7|     
 [6]|                         |     |     |     |     |     |test7

Option Explicit
Sub 分割()

Application.ScreenUpdating = False

    Dim i As Long, ii As Long
    Dim maxrow As Long
    Dim smoji As String
    Dim cmoji As Byte

    Dim rc As VbMsgBoxResult

    '適当に列を消去(書き出しセルの初期化)
    Range("B:J").Clear

    rc = MsgBox("A列に分割する文字列が配置されていますか?", vbYesNo + vbQuestion)
    If rc = vbYes Then
        MsgBox "次の処理に進みます。", vbInformation
    Else
        MsgBox "「いいえ」が押されたので処理を中止します", vbCritical
        Exit Sub
    End If

    maxrow = Cells(Rows.Count, 1).End(xlUp).Row

    smoji = InputBox("分割する文字を指定してください。")

    For i = 1 To maxrow
        cmoji = InStr(Cells(i, "A"), smoji)
        If cmoji > 0 Then
            For ii = 1 To cmoji
                Cells(ii, ii + 1) = Split(Cells(i, 1), smoji)
            Next ii
        End If
    Next i

    Columns("A:J").EntireColumn.AutoFit

End Sub

< 使用 Excel:Excel2021、使用 OS:Windows11 >


[[20230106080353]] 『特定文字で分割して書き出す』(ハイチ)
(既視感) 2023/01/23(月) 07:19:16

アドバイスで上手く処理できたと思ったら
指定文字がスペースの場合は、上手く処理できませんでした。

スペースを他の文字、例えばマイナス(-)などに置換すれば上手く処理できますが
スペースに対応した方法は無いですか ?

Option Explicit
Sub 分割()

Application.ScreenUpdating = False

    Dim i As Long, ii As Long
    Dim maxrow As Long
    Dim smoji As String
    Dim cmoji As Variant '配列
    Dim S_Max As Byte

    Dim rc As VbMsgBoxResult

    '適当に列を消去(書き出しセルの初期化)
    Range("B:J").Clear

    rc = MsgBox("A列に分割する文字列が配置されていますか?", vbYesNo + vbQuestion)
    If rc = vbYes Then
        MsgBox "次の処理に進みます。", vbInformation
    Else
        MsgBox "「いいえ」が押されたので処理を中止します", vbCritical
        Exit Sub
    End If

    maxrow = Cells(Rows.Count, 1).End(xlUp).Row

    smoji = InputBox("分割する文字を指定してください。")

    For i = 1 To maxrow
        cmoji = Split(Cells(i, "A"), smoji)  '指定文字で分割
        S_Max = UBound(cmoji)  '指定文字の総数
        For ii = 0 To S_Max
            Cells(i, ii + 2) = cmoji(ii)
        Next
    Next

    Columns("A:J").EntireColumn.AutoFit

End Sub

(コニャック) 2023/01/23(月) 08:18:14


評価の低いコードでしょうが、現在のコード

Option Explicit
Sub 分割()

Application.ScreenUpdating = False

    Dim i As Long, ii As Long
    Dim maxrow As Long
    Dim smoji As String
    Dim cmoji As Variant '配列
    Dim S_Max As Byte

    Dim rc As VbMsgBoxResult

    '適当に列を消去(書き出しセルの初期化)
    Range("B:J").Clear

    rc = MsgBox("A列に分割する文字列が配置されていますか?", vbYesNo + vbQuestion)
    If rc = vbYes Then
        MsgBox "次の処理に進みます。", vbInformation
    Else
        MsgBox "「いいえ」が押されたので処理を中止します", vbCritical
        Exit Sub
    End If

    maxrow = Cells(Rows.Count, 1).End(xlUp).Row

    smoji = InputBox("分割する文字を指定してください。")

    If smoji = " " Or smoji = " " Then
        For i = 1 To maxrow
            Cells(i, "A") = Replace(Cells(i, "A"), smoji, "-")

        Next
        smoji = "-"
    End If

    For i = 1 To maxrow
        cmoji = Split(Cells(i, "A"), smoji)  '指定文字で分割
        S_Max = UBound(cmoji)  '指定文字の総数
        For ii = 0 To S_Max
            Cells(i, ii + 2) = cmoji(ii)
        Next
    Next

    Columns("A:J").EntireColumn.AutoFit

End Sub

(コニャック) 2023/01/23(月) 08:33:52


 既視感さんのリンク先にある区切り位置は試してみたのだろうか?
(ねむねむ) 2023/01/23(月) 08:40:49

ざっとしか見てないですが、難しく考えすぎでは?

 Sub テキトー()
     Dim cmoji As Variant '配列
     Dim i As Long

     For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
         cmoji = Split(Cells(i, "A"), "-")
         Cells(i, "B").resize(,1+ubound(cmoji))=cmoji
     Next
 End Sub

 ※スマホ&手打ちなのでミスっていたらごめんなさい。

>スペースに対応した方法は無いですか?
普通に区切り文字をスペースにすればよいとおもいますが、動作しないなら、全角と半角どちらで区切っているのか、今一度確認してみては如何でしょうか。

(もこな2) 2023/01/23(月) 08:53:28


確認したら、半角文字列を指定していたはずが全角を指定していました。

ちゃんと半角を指定したら上手く分割されました。

モコナ2さんの以下でもOKでした。

    For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
         cmoji = Split(Cells(i, "A"), smoji)
         Cells(i, "B").Resize(, 1 + UBound(cmoji)) = cmoji
     Next

    Columns("A:J").EntireColumn.AutoFit

(コニャック) 2023/01/23(月) 09:12:50


 文字入力させるなら、2文字以上入力できないように対応してもいいかもですね。

    Sub 分割()
        Dim smoji As String

        If MsgBox("A列に分割する文字列が配置されていますか?", vbYesNo + vbQuestion) <> vbYes Then
            MsgBox "「いいえ」が押されたので処理を中止します", vbCritical
            Exit Sub
        End If
        Do
            smoji = InputBox("分割する文字を指定してください。")
            Select Case Len(smoji)
                Case 1: Exit Do
                Case 0: MsgBox "文字が入力されませんでした。処理を中断します": Exit Sub
                Case Is >= 2: MsgBox "区切り文字は1文字にしてください"
            End Select
        Loop

        '適当に列を消去(書き出しセルの初期化)
        Columns("B:J").ClearContents

        '区切り文字機能で分割
        Range("A1", Cells(Rows.Count, "A").End(xlUp)).TextToColumns _
            Destination:=Range("B1") _
            , DataType:=xlDelimited _
            , OtherChar:=smoji

        'セルの幅を自動調整
        Columns("A:J").EntireColumn.AutoFit
        MsgBox "完了しました"
    End Sub

(稲葉) 2023/01/23(月) 09:33:56


稲葉さんのコードですが、
指定した文字で分割されずにB列にはA列と同じ文字列しか抽出されていません。

(コニャック) 2023/01/23(月) 10:08:57


コニャックさんが提示した例で試してみましたけど、分割されましたよ。
インプットボックスに入力した文字が間違っているとか。

一つ疑問なんですが、下の例だとtestと9は分割されますが、タイプミスですか?

 [3]|test7-test8-test-9-test10|test7|test8|test9|test10
                       ↓
 [3]|test7-test8-test-9-test10|test7|test8|test|  9|test10
(フォーキー) 2023/01/23(月) 10:28:19

 フォーキーさん検証ありがとうございます。

 コニャックさん いただいたデータで何度も何度も試しているので「そりゃないぜ」って感じなんですけど
 実データ教えてもらえますか?

(稲葉) 2023/01/23(月) 10:40:44


(コニャック) さんの現在のコードだと

 ◇初期状態				

    |[A]                    |[B]  |[C]  |[D]  |[E]  				
 [1]|test1 test2 test3 test4|test1|test2|test3|test4				

 ◇処理後				

    |[A]                    |[B]  |[C]  |[D]  |[E]  				
 [1]|test1-test2-test3-test4|test1|test2|test3|test4				

 「-」が処理後に付きますね。良いかどうかわかりませんが				

 A列の空白スペース区切りが				
 下記のようになれば良いのかしら?				

    |[A]                    |[B]  |[C]  |[D]  |[E]  				
 [1]|test1 test2 test3 test4|test1|test2|test3|test4				

 Sub Sample()				

    Dim original_string As String '' 元文字列				
    Dim specified_character  As String '' 指定文字				
    Dim arrange As Variant '' 配列				
    Dim after_division As Variant '' 分割後				
    Dim i&, q&				
    Dim rc As VbMsgBoxResult				

    Range("B:J").Clear				
    rc = MsgBox("A列に分割する文字列が配置されていますか?", vbYesNo + vbQuestion)				
    If rc = vbYes Then				
        MsgBox "次の処理に進みます。", vbInformation				
    Else				
        MsgBox "「いいえ」が押されたので処理を中止します", vbCritical				
        Exit Sub				
    End If				

    specified_character = InputBox("分割する文字を指定してください。")				
    Range("A1").Select				
    i = 0				

    Do				
        original_string = ActiveCell.Offset(i, 0).Value				
        If original_string = "" Then				
            Exit Do				
        End If				
        arrange = Split(original_string, specified_character)				
        q = ActiveCell.Column				
        For Each after_division In arrange				
            ActiveCell.Offset(i, q).Value = after_division				
            q = q + 1				
        Next				
        i = i + 1				
    Loop				

    Range("A1").CurrentRegion.Columns.AutoFit				

 End Sub				

(あみな) 2023/01/23(月) 10:57:33


>実データ教えてもらえますか?

例えば、以下は試用したDATAとB列の結果です。
自前のコードやもこな2さんのコードでは上手く分割されて抽出されています。
(あなみさんのコードも確認が取れました。)

稲葉さんのコードの場合

    |[A]                                                                                     |[B]                                                                                     
 [1]|1st-それだけで僕はどこまでも走れる気がするんだ-ふでやすかずゆき-境宗久-新沼大祐-興村忠美|1st-それだけで僕はどこまでも走れる気がするんだ-ふでやすかずゆき-境宗久-新沼大祐-興村忠美
 [2]|2nd-夢の一員になりたい-岡田達也-黒田晃一郎-川島尚-高澤美佳                              |2nd-夢の一員になりたい-岡田達也-黒田晃一郎-川島尚-高澤美佳                              

成功例(長くなるのでC列はセル幅が短くなっています。)

    |[A]                                                                                     |[B]|[C]                                       |[D]             |[E]       |[F]     |[G]     
 [1]|1st-それだけで僕はどこまでも走れる気がするんだ-ふでやすかずゆき-境宗久-新沼大祐-興村忠美|1st|それだけで僕はどこまでも走れる気がするんだ|ふでやすかずゆき|境宗久    |新沼大祐|興村忠美
 [2]|2nd-夢の一員になりたい-岡田達也-黒田晃一郎-川島尚-高澤美佳                              |2nd|夢の一員になりたい                        |岡田達也        |黒田晃一郎|川島尚  |高澤美佳

すいませんでした。
指摘を受けましたが前提のシート構成が間違っていました。
以下のように訂正させてください。
[3]|test7-test8-test9-test10|test7|test8|test9|test10

あなみさんのコードで分割>抽出 確認できました。
ありがとうございます。

(コニャック) 2023/01/23(月) 12:55:35


既に話の中心が「区切り位置」機能になっていると思いますが何点か。

■1
>モコナ2さんの以下でもOKでした。
>指定した文字で分割されずにB列にはA列と同じ文字列しか抽出されていません。

ちゃんと【ステップ実行】して研究していますか?
結果云々で判断するのではなく、どういう理屈で処理されているのか、想定通りに動作しないのであれば何が問題なのかきちんと分析・把握されたほうがよいとおもいます。

■2
>確認したら、半角文字列を指定していたはずが全角を指定していました。
半角と全角を分けない(どちらでも動作するようにしたい)ということならば、↓のようなアプローチもあるとおもいます。

    Sub 研究用()
        Stop 'ブレークポイントの代わり
        Dim 行 As Long
        Dim 区切文字 As String
        Dim 配列 As Variant

        区切文字 = StrConv(InputBox("区切文字?"), vbNarrow)
        With ActiveSheet.Range("A1").CurrentRegion
            .Offset(0, 1).Clear
            For 行 = 1 To .Rows.Count
                配列 = Split(Replace(.Cells(行, 1).Value, StrConv(区切文字, vbWide), 区切文字), 区切文字)
                .Cells(行, 2).Resize(, 1 + UBound(配列)).Value = 配列
            Next 行
        End With

        ActiveSheet.Range("A1").CurrentRegion.EntireColumn.AutoFit
    End Sub

(もこな2) 2023/01/23(月) 12:56:34


 こっちでは何の問題もないんだけどなぁ
 希望通りの回答が得られたので良かったですね。
(稲葉) 2023/01/23(月) 13:32:42

 >(あなみさんのコードも確認が取れました。) 

 「あみな」さんね。
(とおりすがりんご) 2023/01/23(月) 13:37:58

皆さん、色んな方法での分割方法を教えてもらってありがとうございます。

あみなさん、ニックネームを間違って大変失礼しました。

(コニャック) 2023/01/23(月) 13:51:27


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.