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

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

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

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

5回答

10828閲覧

Excelマクロで指定文字数(31文字)でその文字数の一番後ろの指定文字で改行するExcelマクロの記述方法について

ryuujinn

総合スコア72

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2016/11/21 10:37

編集2016/11/21 10:40

Excelのマクロを使って指定文字数(31文字)で
その文字数の一番後ろの指定文字で改行するマクロの記述方法を探しています

Excelのマクロで指定文字数(31文字)でA1列にある文字列を

その文字数の一番後ろの指定文字で
改行し、B1列に張り付けるマクロの記述方法が分からず困っています

具体的には、一行が31文字で

31文字内に「、」「。」「? 」「(笑)」「・・・・」

「★ 」「!」 「!?」「」」などの文字があった場合、

31文字以内の一番後ろの指定文字で

改行するマクロが作りたいです

下記の文章を読みやすく見栄えの良い文章に改行し1行空けたいです。

31文字以内に指定文字がない場合は31文字で改行するようにし、

処理した結果をB1列に張り付けたいです

A1列にある文字列

例;今日は、朝から天気が良く、真夏日になるらしいので、熱中症対策には十分気を付けたいです。(笑)庭にブールーベリーやひまわりが植えているので暑くなる前に水やりをしたいと思ます★ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫できるのではないかと今から楽しみでなりません!?朝から水やりをした後に近所でラジオ体操をやっているので、姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。「眠い」と思わず声にでてしまう時も多々ありますが、さぼらないように頑張りたいと思います。

↓↓Excelのマクロでしたい処理結果(処理結果をB1に張り付ける)

今日は、朝から天気が良く、真夏日になるらしいので、

熱中症対策には十分気を付けたいです。(笑)

庭にブールーベリーやひまわりが植えているので暑くなる前に水やり

をしたいと思ます★

ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫

できるのではないかと今から楽しみでなりません!?

朝から水やりをした後に近所でラジオ体操をやっているので、

姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。

「眠い」と思わず声にでてしまう時も多々ありますが、

さぼらないように頑張りたいと思います。

秀丸のマクロでは以下の記述で出来たのですが

excelのマクロでどのように記述するのか分からず困っています

ご教授よろしくお願いいたします

setcompatiblemode 0x2000f; // 改行する桁数の定義 #lf_column = 70; // 改行する指定文字列の定義 $lf_str[0] ="、"; $lf_str[1] ="。"; $lf_str[2] ="?"; $lf_str[3] ="!"; $lf_str[4] ="★"; $lf_str[5] ="」"; $lf_str[6] ="(笑)"; $lf_str[7] ="・・・+"; // 中黒が3つ以上連続 #lf_str_num = 8; // 検索用文字列の作成 $search_str = $lf_str[0]; #i = 1; while( #i < #lf_str_num ) { $search_str = $search_str + "|" + $lf_str[#i]; #i = #i + 1; } begingroupundo; disabledraw; replaceallfast "\n", ""; // 改行文字を一旦全削除する gofiletop; // 改行挿入ループ while( 1 ) { beginsel; moveto2 #lf_column, lineno; if( code == eof ) break; // ファイルの最後なら終了 searchup2 "(?\\2)(" + $search_str + ")((?!" + $search_str + "))", regular, inselect; // ※1 insert "\n\n"; } escape; // 選択範囲を解除 insert "\n"; // 最下行の処理 gofiletop; endgroupundo; endmacro;

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

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

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

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

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

guest

回答5

0

ベストアンサー

【再回答】
お詫び

先だって回答した内容に仕様の見落としがあったため、改めて回答させていただきましたm(__)m

処理手順

①対象文字列を取得する (ループ1開始 ~対象文字列がなくなるまでループ処理~)  ②対象文字列から先頭31文字分を切り出す   (ループ2開始 ~区切り文字の数だけループ処理~)    ③切り出した文字列から区切り文字を検索する     ④区切り文字が含まれていた場合、最後の区切り文字までの文字長を取得    ※全ての区切り文字で最長となる文字数を調べる   (ループ2ここまで)   ⑤対象文字列(31文字)から最大の文字長となる区切り位置までの文字列を切り出す   ※区切り文字がひとつも見つからなかった場合、対象文字(31文字)をそのまま使用とする   ⑥⑤で切り出した文字列に改行をつけて出力用文字列に連結する   ⑦出力した文字数分、対象文字列の先頭を削る  ⇒これが次回の対象文字列となります。   ⑧対象文字列がなくなったらループ1終了 (ループ1ここまで) ⑨出力用文字列が変換結果として完成

以下、サンプルソースです。

ソース①:メインロジック(関数名は任意でOK)

Sub Test2() Dim sht As Worksheet Set sht = Sheets("Sheet5") 'シート名は任意に指定 'Set sht = ActiveSheet 'アクティブシートでマクロ実行する場合はこちらでも可 Dim aryPtn As Variant Dim ptn As Variant aryPtn = Array("、", "。", "★", "」", "」", ")", "\)", "\!", "\?", "!", "?", "・+") Dim strOutput As String '結果出力用 Dim strLine As String '1行に出力する文字列 Dim strRest As String '未処理の文字列 'セル(A1)から文字列を取得 strRest = sht.Range("A1").Value Dim iLen As Integer iLen = -1 'ループ処理 Do '先頭31文字を切り出す strLine = Left(strRest, 31) '文字長の初期化 iLen = -1 '置換パターンの数だけループ処理 For Each ptn In aryPtn '最後にマッチした区切り文字までの文字長を調べる Dim iLenWk As Integer iLenWk = FindEx(strLine, ptn) If iLenWk > iLen Then '長い文字長を採用していく iLen = iLenWk End If Next If iLen > 0 Then '区切り文字が見つかった場合、文字列を切り出す strLine = Left(strLine, iLen) End If '切り出した文字列を出力 strOutput = strOutput & strLine '切り出した文字列分を未出力文字列から除去 strRest = Mid(strRest, Len(strLine) + 1) If strRest = "" Then '未出力文字列がなくなったら終了 Exit Do End If '次の行を作る前に改行を追記 strOutput = strOutput & vbLf & vbLf Loop ''結果をB1セルに出力 'sht.Range("B1") = strOutput '結果をクリップボードに出力 Dim objClip As New DataObject With objClip .SetText strOutput 'クリップボードにセットする値を指定 .PutInClipboard 'クリップボードに格納 End With End Sub

ソース②:正規表現検索FindEx(メインロジックで使用している為ファンクション名は変更不可)

'正規表現検索(最終マッチ文字までの文字長を返す) Function FindEx(ByVal vsTarget As String, ByVal vsPattern As String) As Integer Dim iIdx As Integer Dim objReg As Object Dim objMatchs Set objReg = CreateObject("VBScript.RegExp") With objReg .Pattern = vsPattern .IgnoreCase = True .Global = True '正規表現検索 Set objMatchs = .Execute(vsTarget) If objMatchs.Count = 0 Then 'マッチしなかった場合-1 FindEx = -1 Else 'マッチ数を取得 iIdx = objMatchs.Count - 1 'マッチした候補の最終文字列までの文字長を返す FindEx = objMatchs(iIdx).FirstIndex + objMatchs(iIdx).Length End If End With Set objReg = Nothing End Function

参考になれば幸いです。

変換結果

今日は、朝から天気が良く、真夏日になるらしいので、

熱中症対策には十分気を付けたいです。(笑)

庭にブールーベリーやひまわりが植えているので暑くなる前に水やり

をしたいと思ます★

ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫

できるのではないかと今から楽しみでなりません!?

朝から水やりをした後に近所でラジオ体操をやっているので、

姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。

「眠い」と思わず声にでてしまう時も多々ありますが、

さぼらないように頑張りたいと思います。

投稿2016/11/22 12:01

編集2016/11/25 07:11
jawa

総合スコア3013

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

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

退会済みユーザー

退会済みユーザー

2016/11/22 12:48

to jawa様 こちらでも試しに実行してみたところ、変数「ptn」が定義されていなかった事以外は おそらくこの方法が一番だと思います。 ryuujinn様 本マクロは私も実験してみたところ、おそらくは理想的な結果ではないかと思います。
ryuujinn

2016/11/23 04:27

jawaさん、コメント、コードの記載ありがとうございます 記述して頂きましたコードを全て張り付け A1に文字列を挿入し、マクロを実行しようとしたのですが、 「オブジェクトが必要です」と出てしまいます その為、今度はEnd Subまでのコードを記述して張り付けて実行したのですが、 今度は 「コンパイルエラー: SubまたはFunctionが定義されていません。」 とでてしまいました。 また、記述して頂きましたコードでは変換した結果を B1列に張り付ける方法がないようにおもうのですが 私の勘違いでしょうか?
ryuujinn

2016/11/23 04:28

tmkey01さん、コメントありがとうございます 変数「ptn」が定義されていなかったとありますが、 これはどこに追加で記述すればいいのでしょうか?
ryuujinn

2016/11/23 04:57

追記; 変換結果は改行し、一行空ける処理もしたいです ↓変換結果処理 今日は、朝から天気が良く、真夏日になるらしいので、 熱中症対策には十分気を付けたいです。(笑) 庭にブールーベリーやひまわりが植えているので暑くなる前に水やり をしたいと思ます★ ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫 できるのではないかと今から楽しみでなりません!? 朝から水やりをした後に近所でラジオ体操をやっているので、 姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。 「眠い」と思わず声にでてしまう時も多々ありますが、 さぼらないように頑張りたいと思います。 ↑処理結果ここまで 以上となります、お忙しいとは思いますがよろしくお願いいたします
退会済みユーザー

退会済みユーザー

2016/11/23 05:25

ryuujinn様 変数「ptn」の定義ですが、 Sub Test2() Dim aryPtn As Variant   Dim ptn As Variant のように定義すれば問題ございません。 あと、一行開けて、の場合は '切り出した文字列に改行をつけて出力 strOutput = strOutput & strLine & vbCrLf の命令文を    strOutput = strOutput & strLine & vbCrLf & vbCrLf としてみてはいかがでしょうか? (万一セル内での折り返しがうまく行かない場合は、上記の「vbCrLf」を「vbLf」に変更すれば うまくいくはずです。セル内の折り返し「Alt+Enter」は「vbLf」だったと記憶しております。)
jawa

2016/11/24 01:06

>tmkey01さん いろいろとフォローありがとうございます。 指摘の通り、ptnの宣言漏れがありました。 また、オブジェクトが見つからない要因となるものとして ``` strRest = Sheet5.Range("A1").Value ``` の部分でSheet5を参照していました。(私の環境ではSheet5でサンプル作成したためです。) 目的のシートに置き換えていただければ問題ないですが、Sheet5がなければエラーとなってしまいます。 改行に関しても、セル入力時にAlt+Enterで入力する改行はLFですね。 CRLFでもセル内改行はできるのであまり意識する必要はないかもしれませんが、EXCEL的には`vbLf`の方が正しいと思います。 上記についてソースコード修正しました。 >ryuujinnさん ソースコードの実装についてですが、今回提示したサンプルコードはメインロジック(Test2)と正規表現検索(FindEx)の2本でできています。 このうち、メインロジックの部分は任意の名前に変更しても問題ありません。 FindExの方は、この名前でメインロジックから呼び出されている為、名前を変更せずFunction~End Functionまでそのまま利用してください。 ※わかり難かったかもしれないので、サンプルの記載も2本別々にしました。
ryuujinn

2016/11/24 04:50

tmkey01さん、コメント、コードの指摘ありがとうございます、大変助かります jawaさん、コメント、コード修正ありがとうございます 大変見やすいコード嬉しいです EXCEL VBAはSub~End Subだけだとおもっていたのですが Function~End Functionもあるんですね、知りませんでした 修正して頂きましたコードを実行した結果、概ね期待通りの結果なのですが、 秀丸などのテキストに実行結果を張り付けてみるとなぜか、 文章の最後に「"」がついてしまうのですがこれをなくすことはできるのでしょうか? 下が実行した処理結果を秀丸に張り付けた状態です、なぜか最初と最後に「"」が入っています excelのverは2016です "今日は、朝から天気が良く、真夏日になるらしいので、 熱中症対策には十分気を付けたいです。(笑) 庭にブールーベリーやひまわりが植えているので暑くなる前に水やり をしたいと思ます★ ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫 できるのではないかと今から楽しみでなりません!? 朝から水やりをした後に近所でラジオ体操をやっているので、 姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。 「眠い」と思わず声にでてしまう時も多々ありますが、 さぼらないように頑張りたいと思います。 "
jawa

2016/11/24 05:37 編集

エクセルで改行を含むセルの内容は、コピーすると""で括られます。 ※おそらく複数行をまとめてコピーしたときに1セルの内容がどこからどこまでかわかるようにしているのだと思います。 対策としては、 ・貼り付けた後に"を除去する ・セルをコピーする際、セルをダブルクリックして編集モードにしてから全ての文字列を範囲選択してコピーする ・整形した結果をセルではなくクリップボードに出力する などが考えられます。 最終的に秀丸に貼り付けることが目的ならマクロでクリップボードに出力してしまうのが楽かもしれません。 ``` '結果をクリップボードに出力(Microsoft Forms 2.0 Libralyを参照設定に追加する必要あり) Dim objClip As New DataObject With objClip .SetText strOutput 'クリップボードにセットする値を指定 .PutInClipboard 'クリップボードに格納 End With ```
ryuujinn

2016/11/24 08:09

jawaさん、コメント、コードありがとうございます >エクセルで改行を含むセルの内容は、コピーすると""で括られます。 そんな仕様になっているのですね、全く知りませんでした Microsoft Forms 2.0 Object Libraryを参照設定に追加し、 ↓のコードを一番下に張り付けたのですが、コンパイルエラーとてでしまいました。 ``` '結果をクリップボードに出力(Microsoft Forms 2.0 Libralyを参照設定に追加する必要あり) Dim objClip As New DataObject With objClip .SetText strOutput 'クリップボードにセットする値を指定 .PutInClipboard 'クリップボードに格納 End With ``` このようにコードに張り付けたのですが、間違いでしょうか? ``` Sub Test2() Dim sht As Worksheet Set sht = Sheets("Sheet1") 'シート名は任意に指定 'Set sht = ActiveSheet 'アクティブシートでマクロ実行する場合はこちらでも可 Dim aryPtn As Variant Dim ptn As Variant aryPtn = Array("、", "。", "★", "」", "」", ")", "\)", "\!", "\?", "!", "?", "・+") Dim strOutput As String '結果出力用 Dim strLine As String '1行に出力する文字列 Dim strRest As String '未処理の文字列 'セル(A1)から文字列を取得 'strRest = Sheet5.Range("A1").Value strRest = sht.Range("A1").Value Dim iLen As Integer iLen = -1 'ループ処理 Do '先頭31文字を切り出す strLine = Left(strRest, 31) '文字長の初期化 iLen = -1 '置換パターンの数だけループ処理 For Each ptn In aryPtn '最後にマッチした区切り文字までの文字長を調べる Dim iLenWk As Integer iLenWk = FindEx(strLine, ptn) If iLenWk > iLen Then '長い文字長を採用していく iLen = iLenWk End If Next If iLen > 0 Then '区切り文字が見つかった場合、文字列を切り出す strLine = Left(strLine, iLen) End If '切り出した文字列に改行をつけて出力 'strOutput = strOutput & strLine & vbCrLf strOutput = strOutput & strLine & vbLf & vbLf '切り出した文字列分を未出力文字列から除去 strRest = Mid(strRest, Len(strLine) + 1) If strRest = "" Then '未出力文字列がなくなったら終了 Exit Do End If Loop '結果をメッセージ表示 'MsgBox strOutput sht.Range("B1") = strOutput End Sub '正規表現検索(最終マッチ文字までの文字長を返す) Function FindEx(ByVal vsTarget As String, ByVal vsPattern As String) As Integer Dim iIdx As Integer Dim objReg As Object Dim objMatchs Set objReg = CreateObject("VBScript.RegExp") With objReg .Pattern = vsPattern .IgnoreCase = True .Global = True '正規表現検索 Set objMatchs = .Execute(vsTarget) If objMatchs.Count = 0 Then 'マッチしなかった場合-1 FindEx = -1 Else 'マッチ数を取得 iIdx = objMatchs.Count - 1 'マッチした候補の最終文字列までの文字長を返す FindEx = objMatchs(iIdx).FirstIndex + objMatchs(iIdx).Length End If End With Set objReg = Nothing End Function '結果をクリップボードに出力(Microsoft Forms 2.0 Libralyを参照設定に追加する必要あり) Dim objClip As New DataObject With objClip .SetText strOutput 'クリップボードにセットする値を指定 .PutInClipboard 'クリップボードに格納 End With ```
jawa

2016/11/25 00:34 編集

「これを使うと動くよ」とネット上で紹介されているコードをただコピペして動かすだけでは、結果的に動くものが出来上がったとしても何も身に付きません。 面倒ですが、実装するコードの意味を1行ずつ理解することが大事です。 今回ご紹介したコードは何をするものだったでしょうか? ⇒整形した結果を「セルB1に出力せずに」「クリップボードに出力する」 それがわかれば、そのコードをどこに記述すればいいかもわかると思います。 意地悪な言い方に聞こえるかもしれませんが、まずはちょっと考えて、整理して、がんばっていろいろ試してみてください。 一番難しそうな参照設定の部分を乗り越えているようですので、きっとできます。 ⇒がんばったけどやっぱりわからなかった場合はご相談くださいm(__)m
ryuujinn

2016/11/25 03:21

jawaさん、コメントありがとうございます 確かにjawaさんの言う通りだと思いますので 色々と試してみたらできるようになりました。 あの位置に入れないといけないとは思いませんでした、 あと、一つ、質問させてください。 最終行だけ、改行しないようにしたいのですが、それはどのようにすればいいのでしょうか? ``` 朝から水やりをした後に近所でラジオ体操をやっているので、 姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。 「眠い」と思わず声にでてしまう時も多々ありますが、 さぼらないように頑張りたいと思います。 ``` 上記のように最終行だけ、改行無しにしたいと考えております お忙しい中コード、コメントして頂きまして本当にありがとうございます
jawa

2016/11/25 04:28 編集

今の処理の流れだと、1行出力するたびに必ず改行を2つ付けているので、最終行にも改行が2つ付いてしまいます。 対策としては、  方法①:改行は2つずつつけておき、最後に不要な改行を除去する  方法②:最終行には改行をつけない という方法があると思います。 --- 方法①は現在の処理をそのまま使い、最後に出力内容を調整する方法です。 クリップボードに出力する直前に後ろ2文字(改行2つ分)を除去してあげればいいだけなので、コードはこちらの方が簡単に実装できると思います。 ``` '出力文字列の長さ-2文字の文字列に変更する strOutput = Left(strOutput, Len(strOutput) - 2) ``` --- 方法②は最初から不要な改行をつけないように文字列を作成する方法です。 方法①よりも実装は複雑になりますが、こちらの方が無駄のないエレガントなコードですので、私ならこちらを採用します。 ``` ''切り出した文字列に改行をつけて出力 ''strOutput = strOutput & strLine & vbCrLf 'strOutput = strOutput & strLine & vbLf & vbLf '切り出した文字列を、改行をつけずに出力 strOutput = strOutput & strLine '切り出した文字列分を未出力文字列から除去 strRest = Mid(strRest, Len(strLine) + 1) If strRest = "" Then '未出力文字列がなくなったら終了 Exit Do End If '改行は最終行でない場合にだけ付加する strOutput = strOutput & vbLf & vbLf ``` 方法②のサンプルコードでは、出力文字列の作られる流れを少し変えています。 この変更で最終行に改行がつかなくなる理由が理解できれば、今回のコードに関しては十分理解できていると思います。 Doループがどのようにループして、文字列がどのように連結されていくか、実際のループ処理の流れを追ってみると理解しやすいと思いますので頑張ってみてください。
ryuujinn

2016/11/25 06:13

jawaさん、引き続きコードありがとうございます エレガントなコードを使用したかったのですが、結果が思うようにいかず、 1の方を使わせて頂きます -2を-1にして使うと思ったような処理結果が得られました '出力文字列の長さ-1文字の文字列に変更する strOutput = Left(strOutput, Len(strOutput) - 1) 今回は親切丁寧にご回答、コメント、コード記載本当にありがとございました これに懲りずに今後とも質問が有るときにはよろしくお願い致します
jawa

2016/11/25 07:05

こちらの環境では strOutput = Left(strOutput, Len(strOutput) - 2) できれいに2文字(改行2つ分)消してくれましたが、(逆に-1では改行が1つ残るのですが)、これは環境の違い(当方Excel2010で動作)かもしれません。 期待する結果が得られたようで何よりです。 最後に、参考までに提示したサンプルソースをエレガント(笑)なコードに編集しておきますね。
ryuujinn

2016/11/26 12:03

jawaさん、エレガントな書き換えありがとうございます しかし、試しにエレガントに書き換えて頂きました、サンプルソースを 実行してみたのですが、何も処理されない結果になりました なぜなのでしょうか?
jawa

2016/11/28 02:18 編集

こちらで動作確認できているものを掲載しているつもりですが、どこで意図しない動きになっているかはつかめていますでしょうか? あやしいのは ・対象シートの指定  ⇒サンプルはSheet5になっています。 ・対象セルの指定  ⇒サンプルコードでは対象シートのA1セルを取得しています。 ・出力先の確認  ⇒出力先は当初はメッセージ表示、次の修正でB2セルとしていましたが、   最終的なサンプルではクリップボード出力となっています。   秀丸などに貼り付けなければ何も動作していないように見えるかもしれません。 このあたりでしょうか。 ところでデバッグ実行はご存知でしょうか? VBエディタ画面でデバッグしたいコードにカーソルを置き、ステップイン(F8)でデバッグ実行を開始すると処理を1行ずつ追いながら流すことができます。 意図しない動きとなっている箇所を調査する際に便利な機能です。 ご確認ください。
退会済みユーザー

退会済みユーザー

2016/11/28 02:45

ryuujinn様 もしかして、「セルに出力されない=何も処理されていない」と思い込んでおられるのでは? 「ホーム」タブの「クリップボード」の右下の記号をクリックすると、クリップボードに 「直接」結果が代入されているのが確認できるかと思います。 (こちらでも確認済み) セル出力を有効にするには、何行目かにコメントアウトされた部分がございますので、 そこを有効にすると出力されますよ? (コードをよく見直すと…) Hint:jawa様の「ステップ実行」を行なうと、簡単に見つかる場所です。 是非やってみてください。
ryuujinn

2016/11/28 07:28

jawaさん、コメントありがとうございます 今までセルに出力もしていたので勘違いしておりました お騒がせしてすいませんでした tmkey01さん、ご指摘ありがとうございます 大変助かりました
ryuujinn

2016/11/30 00:47

jawaさん、もう一つ質問させてください このコードを他のsheet1以外にもsheet2、sheet3にも使用したい場合、 Set sht = Sheets("sheet1") 上記の部分はどのように追記すればいいのでしょうか?
jawa

2016/11/30 03:03

対象のシートが複数になるとのことですが、それらのシートから1つ選んで処理すればいいのか、対象シートを連続で処理したいのかによって作りが変わってきます。 連続実行でなくてもよいのであれば、例えば処理したいシートをアクティブにしてから処理を開始しする方法が簡単だと思います。 ``` 'アクティブシートを処理対象シートに設定する Set sht = ActiveSheet ``` 対象シートを連続で処理したい場合、通常はループ処理で行います。 ``` Dim arySheetNm As Variant arySheetNm = Array("Sheet1", "Sheet2", "Sheet3") Dim shtNm As Variant For Each shtNm In arySheetNm Set sht = Sheets(shtNm) '(中略) Next shtNm ``` ただし、今回の場合は結果をクリップボードに出力しています。 1シート処理する毎にクリップボードに結果を出力しますが、そのまま次のシートを連続処理した場合、その前のシートで作成した結果に上書く形でクリップボードに出力してしまいます。 というわけで今回の処理は連続処理には不向きです。 どうしても連続で行いたい場合は、1シート処理が終わるたびにメッセージボックスを表示するなどして処理を中断し、その間に秀丸などに貼り付ける、その後メッセージボックスを閉じて処理再会、などのような工夫が必要です。 ここからは余談ですが、こういった機能拡張を繰り返すと、1つの関数に膨大な処理が記載され、煩雑になっていき、その後のメンテナンス性も悪くなっていってしまいます。 今回の場合、 ``` Sub Test2(ByVal vsShtNm As String) Set sht = Sheets(vsShtNm) '(中略) End Sub Sub Main() Test2 "Sheet1" Test2 "Sheet2" Test2 "Sheet3" End Sub ``` といった具合に、シート名を引数で受け取り処理する変換関数と、対象シートを指定して変換機能を呼び出すメイン関数に分けたほうがすっきりすると思います。 ※今回、手元に実行環境がないため全て机上ロジックです。そのまま動作する保証はありませんのでご容赦ください。
ryuujinn

2016/12/02 04:58

jawaさん、コメント、コード記載ありがとうございます 大変うれしく助かりました ありがとうございました
guest

0

記載いただいている条件を全て区切ると、結果は期待されている内容にはなりません。
例えば"、"のたびに改行されますし、「!?」も「!」で改行、「?」でまた改行されるはずです。
※区切り文字が連続して出現した場合はひと塊として扱うというルール(仕様)でもあれば、もう少し期待する結果となるかもしれません。

前提仕様には問題がありそうですが、「目的の文字を見つけて改行する」という処理の手順としては以下のような流れで実現できると思います。


処理手順
①対象文字列を取得する

②対象文字列から先頭31文字分を切り出す

③切り出した文字列に区切り文字が含まれていたら、区切り文字の後にタブ文字を挿入する

④③で編集した文字列をタブ文字で分割する

⑤④の分割結果文字列に改行をつけて出力用文字列に連結する

⑥出力した文字数分、対象文字列の先頭を削る
⇒これが次回の対象文字列となります。

⑦対象文字列がなくなるまで②~⑥を繰り返す


補足1:
③でタブ文字を挿入しているのは、④で使用しているSplit関数で複数文字を指定した分割ができないため、事前準備をしています。
区切り文字の後ろにタブ文字(通常ではセル内に入力されない文字)を挿入し、Split関数でこのタブ文字を見つけて分割する、という流れになります。

補足2:
④のSplit関数でタブ文字が含まれていた場合、タブ文字ごとに分割した文字列配列を返します。
配列の先頭の文字列が、区切れ目の文字列となります。
もしタブ文字が見つからなかった場合、Split関数は全体の文字列(31文字)をそのまま返します。

サンプルコード

以下、上記の手順で作成したサンプルです。
区切り文字の条件に、複数個連続する「・」で改行というものがあったため、区切り文字の検索には正規表現検索を採用しています。

Sub Test() Dim aryPtn As Variant '区切り文字 aryPtn = Array("。", ")", "★", "\)", "\!", "!?", "\!\?", "・+") Dim strOutput As String '結果出力用 Dim strLine As String '1行に出力する文字列 Dim strRest As String '未処理の文字列 'セル(A1)から文字列を取得 strRest = Sheet5.Range("A1").Value 'ループ処理 Do '31文字分を抽出 strLine = Left(strRest, 31) '置換パターンの数だけループ処理 Dim strTemp As String '置換結果文字列 strTemp = strLine For Each ptn In aryPtn '区切り文字の後ろにタブ文字を挿入する(正規表現置換)※ptn文字列 ⇒ ptn文字列+タブ文字に置換 strTemp = ReplaceEx(strTemp, "(" & ptn & ")", "$1" & vbTab) Next '最初の区切りまでの文字列を取得する strLine = Split(strTemp, vbTab)(0) '切り出した文字列に改行をつけて出力 strOutput = strOutput & strLine & vbCrLf '切り出した文字列分を未出力文字列から除去 strRest = Mid(strRest, Len(strLine) + 1) If strRest = "" Then '未出力文字列がなくなったら終了 Exit Do End If Loop '結果をメッセージ表示 MsgBox strOutput End Sub '正規表現置換 Function ReplaceEx(vsTarget As String, vsPattern As String, vsReplace As String ) As String Dim objReg As Object Dim strRet As String Set objReg = CreateObject("VBScript.RegExp") With objReg .Pattern = vsPattern .IgnoreCase = True .Global = True '正規表現置換 strRet = .Replace(vsTarget, vsReplace) End With ReplaceEx = strRet Set objReg = Nothing End Function

参考になれば幸いです。

投稿2016/11/22 10:15

jawa

総合スコア3013

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

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

jawa

2016/11/22 12:00

「前提仕様に間違いがある」などとえらそうに指摘してしまいましたが、 >31文字以内の「一番後ろの指定文字」で改行する という部分を見落としてしまっていました。 ・・・大変失礼しましたm(__)m 改めて回答させていただきましたので、参考になれば幸いです。 ※ここに追記すると長くなってしまう&この回答も消すにはもったいないので、 別途回答立てさせていただきました。
ryuujinn

2016/11/23 04:33

jawaさん、コメント、コード記載ありがとうございます 丁寧に回答して頂きまして嬉しいです
guest

0

VBAで作ってみました。
突貫なので全然きれいなソースではないのですが、参考になれば幸いです。
ボタンを適当に作って、ボタン押下後の処理となっております。

※2016/11/24 修正

VBA

1' 改行する指定文字列の定義(増やしたい時は最後尾に「,追加文字列」とする) 2Private Const strSplit As String = "、,。,?,?,!,!,★,」,(笑),・・・" 3 4'上記改行する文字列以外で使いそうもない記号・文字 5Private Const strReplace As String = "□" 6 7'ボタン押下処理 8Private Sub CommandButton1_Click() 9 Dim strA1 As String ' A1の文字列を格納 10 Dim valNewLine As Variant ' 改行指定文字列を格納 11 Dim valSplitA1 As Variant ' A1の文字列を区切ったものを格納 12 Dim strMainSent As String ' A1文字列を色々弄っては格納する文字列 13 Dim strTempSent As String ' strLastSentに入れる前の仮 14 Dim strLastSent() As String ' 最終的に出力するものを格納 15 16 Dim intNum As Integer ' 繰り返した回数 17 Dim blnFlag As Boolean ' フラグ(true:繰り返す、false:条件満たして終了) 18 Dim i As Integer ' For文で使用 19 20 'B列クリア 21 Columns("B").Clear 22 23 'A1の長文を格納 24 If Cells(1, 1).Value = "" Then 25 MsgBox ("A1セルに文字がありません。") 26 Exit Sub 27 End If 28 strA1 = Cells(1, 1).Value 29 30 '改行する指定文字列 31 valNewLine = Split(strSplit, ",") 32 33 '指定文字列文繰り返す 34 strMainSent = strA1 35 For Each nl In valNewLine 36 strMainSent = Replace(strMainSent, nl, nl & strReplace) 37 Next nl 38 39 '--------------------------------------- 40 ' ここまでで、指定文字列の後ろにすべて 41 ' 使いそうもない記号・文字が加わっている 42 '--------------------------------------- 43 44 'A1の文字列を区切る 45 valSplitA1 = Split(strMainSent, strReplace) 46 47 '色々初期化 48 ReDim strLastSent(0) 49 blnFlag = True 50 intNum = 0 51 strTempSent = "" 52 53 'A1の文字列を整える 54 Do While blnFlag 55 If intNum <> 0 Then 56 57 '----------------------------------------- 58 ' 文字列の数が問題ないか確認(文字数) 59 ' 文字数ならLen、バイトで見るならLenBを使用 60 ' 今回は文字数で実施してます 61 '----------------------------------------- 62 63 '単体で32文字より大きかった時の処理 64 If Len(strTempSent) > 31 Then 65 ReDim Preserve strLastSent(UBound(strLastSent) + 1) 66 strLastSent(UBound(strLastSent)) = Left(strTempSent, 31) 67 strTempSent = Mid(strTempSent, 32) 68 End If 69 70 '組み合わせで32文字未満かどうかの処理 71 If Len(strTempSent + valSplitA1(intNum)) < 32 Then 72 strTempSent = strTempSent + valSplitA1(intNum) 73 Else 74 '格納配列を増やして最後尾に格納 75 ReDim Preserve strLastSent(UBound(strLastSent) + 1) 76 strLastSent(UBound(strLastSent)) = strTempSent 77 strTempSent = valSplitA1(intNum) 78 End If 79 80 Else 81 '初回のみ 82 strTempSent = valSplitA1(0) 83 End If 84 85 '最終配列か確認 86 If intNum = UBound(valSplitA1) Then 87 blnFlag = False 88 89 '最後の文字列を格納 90 ReDim Preserve strLastSent(UBound(strLastSent) + 1) 91 strLastSent(UBound(strLastSent)) = strTempSent 92 End If 93 94 intNum = intNum + 1 95 Loop 96 97 '出力処理① -- 以下、変更箇所 98 For i = 1 To UBound(strLastSent) 99 Cells(1, 2).Value = Cells(1, 2).Value & strLastSent(i) & vbLf & vbLf 100 Next i 101 102 '--------------------------------------------------------- 103 ' もし最終行「さぼらないように頑張りたいと思います。」の後に 104 ' 改行を入れたくなければ以下4行の先頭「'」を外して 105 ' 上記出力処理①のFor~Nextの3行の先頭に「'」をつけてください 106 '---------------------------------------------------------- 107 '出力処理② 108' For i = 1 To UBound(strLastSent) - 1 109' Cells(1, 2).Value = Cells(1, 2).Value & strLastSent(i) & vbLf & vbLf 110' Next i 111' Cells(1, 2).Value = Cells(1, 2).Value & strLastSent(UBound(strLastSent)) 112 113End Sub 114

出力結果は以下の通りです。

-------- 出力結果 ここから -------------

今日は、朝から天気が良く、真夏日になるらしいので、

熱中症対策には十分気を付けたいです。(笑)

庭にブールーベリーやひまわりが植えているので暑くなる前に水やり

をしたいと思ます★

ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫

できるのではないかと今から楽しみでなりません!?

朝から水やりをした後に近所でラジオ体操をやっているので、

姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。

「眠い」と思わず声にでてしまう時も多々ありますが、

さぼらないように頑張りたいと思います。

-------- 出力結果 ここまで -------------

長々となってしまいましたが、要は指定文字列の後ろに指定文字列以外の使いそうもない記号(今回のソースだと□)を置いて、そこから31字以上かどうか判断していく、という方法で作成しました。

参考になれば幸いです。

### 追記1

ご希望の処理にそっておらず申し訳ございません。
出力処理箇所を修正いたしましたので、お試し頂ければと思います。
出力箇所①、②は最終行の出力に合わせてどちらかを選んで頂ければと思います。

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

### 追記2

EXCELのB1セルをコピペして秀丸などに張り付けた時に先頭と最後尾に「"」が入ってしまう現象を確認いたしました。
おそらく、こちらのサイトが参考になるかと思いますエクセル術
こちらのサイトで色々手法が乗っておりますが、その中の「エクセルのコピー時にダイレクトにクリップボード操作するマクロ」が良いのではないかと思いました。

上記の方法を現状に合わせるならば、今までのソースをボタン1とするならば、ボタン2を作って以下のソースをボタン2の処理とします。

VBA

1'ボタン2の処理 2Private Sub CommandButton2_Click() 3 Dim buf As String, buf2 As String, CB As New DataObject 4 buf = ActiveCell 5 With CB 6 .SetText buf ''変数のデータをDataObjectに格納する 7 .PutInClipboard ''DataObjectのデータをクリップボードに格納する 8 .GetFromClipboard ''クリップボードからDataObjectにデータを取得する 9 buf2 = .GetText ''DataObjectのデータを変数に取得する 10 End With 11End Sub 12

(ツールの参照設定にある Microsoft Forms 2.0 Object Library を使えるようにする必要あり。私の環境では最初から使えるようになっていたのでもしかしたら設定不要かもしれません)

これを作成したのち、
① ボタン1押下(これで「今日は、朝から天気が良く、~」の文章が改行してB1に作られる)
② B1セルを選択
③ ボタン2押下
④ 秀丸などに張り付ける

という方法でご希望の方法が達成されるかと思います。
(③実行しても特にアクションとかありませんが、④の貼り付けができます)

ボタン2作るのが面倒な場合は、セルをコピーするのではなく、中を選択(B1セルでF2を選択)してからすべてコピペしたのちに秀丸に張り付ければこの現象は回避できます。

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

### 追記3
回答および追記2のソースを一つのボタンで実行できるようにまとめてみました。
(言われずともボタン1つで完了させるべきでした。横着してしまいすみません)

VBA

1' 改行する指定文字列の定義(増やしたい時は最後尾に「,追加文字列」とする) 2Private Const strSplit As String = "、,。,?,?,!,!,★,」,(笑),・・・" 3 4'上記改行する文字列以外で使いそうもない記号・文字 5Private Const strReplace As String = "□" 6 7'ボタン押下処理 8Private Sub CommandButton1_Click() 9 Dim strA1 As String ' A1の文字列を格納 10 Dim valNewLine As Variant ' 改行指定文字列を格納 11 Dim valSplitA1 As Variant ' A1の文字列を区切ったものを格納 12 Dim strMainSent As String ' A1文字列を色々弄っては格納する文字列 13 Dim strTempSent As String ' strLastSentに入れる前の仮 14 Dim strLastSent() As String ' 最終的に出力するものを格納 15 16 Dim intNum As Integer ' 繰り返した回数 17 Dim blnFlag As Boolean ' フラグ(true:繰り返す、false:条件満たして終了) 18 Dim i As Integer ' For文で使用 19 20 '修正:B列 → B1セルクリア 21 'Columns("B").Clear 22 Range("B1").Clear 23 24 'A1の長文を格納 25 If Cells(1, 1).Value = "" Then 26 MsgBox ("A1セルに文字がありません。") 27 Exit Sub 28 End If 29 strA1 = Cells(1, 1).Value 30 31 '改行する指定文字列 32 valNewLine = Split(strSplit, ",") 33 34 '指定文字列文繰り返す 35 strMainSent = strA1 36 For Each nl In valNewLine 37 strMainSent = Replace(strMainSent, nl, nl & strReplace) 38 Next nl 39 40 '--------------------------------------- 41 ' ここまでで、指定文字列の後ろにすべて 42 ' 使いそうもない記号・文字が加わっている 43 '--------------------------------------- 44 45 'A1の文字列を区切る 46 valSplitA1 = Split(strMainSent, strReplace) 47 48 '色々初期化 49 ReDim strLastSent(0) 50 blnFlag = True 51 intNum = 0 52 strTempSent = "" 53 54 'A1の文字列を整える 55 Do While blnFlag 56 If intNum <> 0 Then 57 58 '----------------------------------------- 59 ' 文字列の数が問題ないか確認(文字数) 60 ' 文字数ならLen、バイトで見るならLenBを使用 61 ' 今回は文字数で実施してます 62 '----------------------------------------- 63 64 '単体で32文字より大きかった時の処理 65 If Len(strTempSent) > 31 Then 66 ReDim Preserve strLastSent(UBound(strLastSent) + 1) 67 strLastSent(UBound(strLastSent)) = Left(strTempSent, 31) 68 strTempSent = Mid(strTempSent, 32) 69 End If 70 71 '組み合わせで32文字未満かどうかの処理 72 If Len(strTempSent + valSplitA1(intNum)) < 32 Then 73 strTempSent = strTempSent + valSplitA1(intNum) 74 Else 75 '格納配列を増やして最後尾に格納 76 ReDim Preserve strLastSent(UBound(strLastSent) + 1) 77 strLastSent(UBound(strLastSent)) = strTempSent 78 strTempSent = valSplitA1(intNum) 79 End If 80 81 Else 82 '初回のみ 83 strTempSent = valSplitA1(0) 84 End If 85 86 '最終配列か確認 87 If intNum = UBound(valSplitA1) Then 88 blnFlag = False 89 90 '最後の文字列を格納 91 ReDim Preserve strLastSent(UBound(strLastSent) + 1) 92 strLastSent(UBound(strLastSent)) = strTempSent 93 End If 94 95 intNum = intNum + 1 96 Loop 97 98 '出力処理① 99 For i = 1 To UBound(strLastSent) 100 Cells(1, 2).Value = Cells(1, 2).Value & strLastSent(i) & vbLf & vbLf 101 Next i 102 103 '--------------------------------------------------------- 104 ' もし最終行「さぼらないように頑張りたいと思います。」の後に 105 ' 改行を入れたくなければ以下4行の先頭「'」を外して 106 ' 上記出力処理①のFor~Nextの3行の先頭に「'」をつけてください 107 '---------------------------------------------------------- 108 '出力処理② 109' For i = 1 To UBound(strLastSent) - 1 110' Cells(1, 2).Value = Cells(1, 2).Value & strLastSent(i) & vbLf & vbLf 111' Next i 112' Cells(1, 2).Value = Cells(1, 2).Value & strLastSent(UBound(strLastSent)) 113 114 '-- ここから追加 -- 115 116 'B1セルにカーソルをあてる 117 Cells(1, 2).Select 118 119 'コード2 120 Dim buf As String, buf2 As String, CB As New DataObject 121 buf = ActiveCell 122 With CB 123 .SetText buf ''変数のデータをDataObjectに格納する 124 .PutInClipboard ''DataObjectのデータをクリップボードに格納する 125 .GetFromClipboard ''クリップボードからDataObjectにデータを取得する 126 buf2 = .GetText ''DataObjectのデータを変数に取得する 127 End With 128End Sub

変更箇所としては、B1セルにカーソルを移動させてからクリップボードにコピーをするようにしました。
処理完了時点でクリップボードにコピーされておりますので、処理完了後に秀丸を開いて張り付ければご希望の処理になっているかと思います。ご確認くださいませ。

ボタン操作の中にほぼソースを入れてしまったのでまったくもって綺麗とはかけ離れたソースになってしまいました・・・。お好みでプロシージャ分けなどして頂ければと思います。

参考になれば幸いです。

投稿2016/11/22 02:18

編集2016/11/25 07:07
SASAHARA

総合スコア247

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

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

ryuujinn

2016/11/23 04:49

SASAHARAさん、コメント、コード記載ありがとうございます 記述して頂きましたコードを実行した結果 改行がセル内ではなく改行ごとにセルが分かれてしまったのですが 全ての文字列を1つのセル内で改行し一行空けてB1列セルに入れることは難しいのでしょうか? 具体的には↓処理結果 今日は、朝から天気が良く、真夏日になるらしいので、 熱中症対策には十分気を付けたいです。(笑) 庭にブールーベリーやひまわりが植えているので暑くなる前に水やり をしたいと思ます★ ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫 できるのではないかと今から楽しみでなりません!? 朝から水やりをした後に近所でラジオ体操をやっているので、 姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。 「眠い」と思わず声にでてしまう時も多々ありますが、 さぼらないように頑張りたいと思います。 ↑処理結果ここまで をB1セルに改行し、一行空けて全て入れたいです
SASAHARA

2016/11/24 01:41

回答欄のソースを修正いたしましたので、ご確認頂ければと思います。
SASAHARA

2016/11/24 01:45

念のため追記です。 私の環境は、  Windows 7 Professional  Excel2010 で、作成および確認しております。
ryuujinn

2016/11/24 05:11

SASAHARAさん、回答欄のソースの修正ありがとうございます 大変助かります、また、最終行に改行を入れたい場合と入れたくない場合等も 追加で記載して頂きまして大変助かります 聞こうかと思ってい事なので事前にコードに記載して頂きまして嬉しいです 回答欄に記載して頂きましたコードを使用して実行した結果、 概ね期待通りの結果になったのですが、 実行結果を秀丸などのテキストに張り付けたら なぜか、Excelには記載されていないのに 文字の最初と最後に「"」がついてしまいます 以下がその現象です ↓ "今日は、朝から天気が良く、真夏日になるらしいので、 熱中症対策には十分気を付けたいです。(笑) 庭にブールーベリーやひまわりが植えているので暑くなる前に水やり をしたいと思ます★ ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫 できるのではないかと今から楽しみでなりません!? 朝から水やりをした後に近所でラジオ体操をやっているので、 姪っ子と甥っ子を連れて、ラジオ体操に今から行ってきます。 「眠い」と思わず声にでてしまう時も多々ありますが、 さぼらないように頑張りたいと思います。 " ↑秀丸などのテキストに張り付けた結果です また、試しに文字を手打ちでエクセルに打ち込みそれをコピーして 秀丸などのテキストで張り付けた結果は このような現象はおきませんでした Excelのverは2016で、Windows10です
SASAHARA

2016/11/24 05:47

回答欄に追記しましたのでご確認いただければと思います。
ryuujinn

2016/11/24 10:35 編集

SASAHARAさん、コメント、コード追記ありがとうございます 参照設定の件もご指摘頂きましてありがとうございます 私の方では設定されていなかったので、助かりました コード1、2は統合して、使う事はできないのでしょうか? コードを統合し、コード1を実行した後、コード2を実行し、クリップボードに直接コピーをしたいと思っています
SASAHARA

2016/11/24 11:17

ボタン1つに処理をまとめたものを追記3に記載しました。 (ここの返信欄だとソースがきれいに見えないので、上の回答欄に追記を続けさせてもらっております)
ryuujinn

2016/11/25 02:30

SASAHARAさん、コメント、コードありがとうございます 追記欄に奇麗に見やすくコードを張り付けて頂きまして嬉しいです 無事にやりたいことが出来るようになりました 大変助かりました ありがとうございました
ryuujinn

2016/11/25 06:15

SASAHARAさん、今気づいたのですが、 B1以下に記載されていた文字がこの処理をすると消えてしまう現象がでるのですが この現象が起きないようにすることは可能なのでしょうか? B2、B3などに入力していた文字がこの処理をすると消えてしまいます。
SASAHARA

2016/11/25 07:12

追記3のソースを修正しました。 コメントを読んでいただければわかるかと思って放置していたのですが、(最初の名残で)B列をクリア(初期化)しておりました。現在の追記3はB1セルのみ初期化しております。 ---- 変更箇所 ------ '修正:B列 → B1セルクリア 'Columns("B").Clear ← こちらは不要なのでコメントアウト(行ごと削除してもよい) Range("B1").Clear  ← 追加 ------------------------------ 以上、よろしくお願いいたします。
ryuujinn

2016/11/26 12:05

SASAHARAさん、何度も丁寧にご対応頂きましてありがとうございました こちらこそ、コメントの部分を見落としていてお手数をお掛けしてしまい、大変申し訳ありませんでした 追記3のソースの修正もありがとうございます 嬉しいです
guest

0

3年ぶりにVBA触ったので手こずりましたが、
以下でどうでしょうか。

VBA

1Option Explicit 2 3Sub Kaigyou() 4 Const targetCell = "A1" 5 Const ResultCell = "B1" 6 Dim text As String 7 Dim targetArr As Variant 8 targetArr = Array("、", "。", "?", "!", "★", "」", "(笑)", "・・・") 9 10 Application.ScreenUpdating = False 11 12 text = ActiveSheet.Range(targetCell).Value 13 14 Dim tmp As Variant 15 16 For Each tmp In targetArr 17 text = Replace(text, tmp, tmp & vbCrLf) 18 Next 19 20 ActiveSheet.Range(ResultCell).Value = text 21 22 Application.ScreenUpdating = True 23End Sub 24

出力結果は理想通りではないかもですが、
指定文字で改行すると以下になります。

"今日は、
朝から天気が良く、
真夏日になるらしいので、
熱中症対策には十分気を付けたいです。
(笑)
庭にブールーベリーやひまわりが植えているので暑くなる前に水やりをしたいと思ます★
ブルーベリーの実がなってきて色づいてきたのでもう少ししたら収穫できるのではないかと今から楽しみでなりません!

朝から水やりをした後に近所でラジオ体操をやっているので、
姪っ子と甥っ子を連れて、
ラジオ体操に今から行ってきます。
「眠い」
と思わず声にでてしまう時も多々あり"

投稿2016/11/21 12:58

編集2016/11/21 13:02
mukkun

総合スコア882

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

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

ryuujinn

2016/11/23 04:40

mukutaJapさん、コメント、コード記載ありがとうございます 31文字以内に指定の文字列が2個以上あった場合、31文字内の一番後ろで改行するように したいのですが、それは難しいのでしょうか? 具体的には以下のようにしたいです 今日は、 朝から天気が良く、 真夏日になるらしいので、 熱中症対策には十分気を付けたいです。 (笑)
guest

0

横入り失礼します。

取り敢えず、31文字ごとにvbLfを入れてセルに代入するコードは何とかできましたが、
特定文字で折り返すとなると、他の方々のコードをご参考頂くか、下記コードの正規表現パターンを
変更する方法もありかと(正規表現については私もあまり詳しくないので、申し訳ございません…)。

Excel

1 2Sub Enter_sample1() 3'このマクロでは、31文字ごとにvbLrを2回入れて、セルA1の文字列をセルA2に代入可能。 4'前提条件として、「ツール→参照設定」で、「MicroSoft VBScript Regular Expressons 5.5」 5'にチェックを入れること。 6 7Dim i As Long 'ループ変数 8Dim inputStr As String '処理前文字列 9Static outputStr As String '処理後文字列 10 11Dim Rexp As RegExp '正規表現を使用可能とするオブジェクト 12Dim strPtn As String '正規表現パターン(VBScript準拠) 13Dim mc As MatchCollection 'パターンマッチしたものの集合 14Dim chgstr() As String 'マッチした文字列にvbLfを結合したものを格納する変数 15 16 17Set Rexp = New RegExp 18outputStr = "" '処理後文字列の初期化(Static変数なので、変数内容をクリアにする必要がある) 19 20 21strPtn = ".{1,31}" '任意の1文字以上31文字以下の文字列を抽出する正規表現 22inputStr = Cells(1, 1).Value '入力文字列 23 24'正規表現に基づいた文字列処理 25With Rexp 26 27 .Pattern = strPtn '適用する正規表現パターン 28 .Global = True '文字列全体を正規表現対象とする 29 30 Set mc = .Execute(inputStr) '正規表現検索をする命令 31 32End With 33 34 ReDim chgstr(mc.Count - 1) 35 36 37 '正規表現で抽出した文字列に、vbLfを2回追加する(セル内の折り返しはLF) 38 39 For i = 0 To mc.Count - 1 40 41 chgstr(i) = mc.Item(i) & vbLf & vbLf 42 43 Next i 44 45 '出力文字列を作成 46 47 For i = 0 To UBound(chgstr) 48 49 outputStr = outputStr & chgstr(i) 50 51 Next i 52 53 'セルA2に文字列を代入する(B1の場合はCells(1,2)とする) 54 'A2としたのは処理結果を確認できるようにしたため 55 56 Cells(2, 1).Value = outputStr 57 58'終了処理(全てのオブジェクトを開放、Static変数を空にする) 59 60Set Rexp = Nothing 61Set mc = Nothing 62outputStr = "" 63 64End Sub 65

実行結果です。
マクロ実行結果

もし正規表現に詳しい方おられましたら、ご意見等お願い致します。
(私ももう少しやってみようと思います。面白い試みだと思いましたので。)

参考(翔泳社会員登録が必要)VBAで正規表現を使う

追記:

ryuujinn様

ふと思いましたが、コードを追加する場合、「1つのSub内にすべて入れ込まないといけない」と
思っておりませんか?

その場合、コードが非常に縦方向に長くなり、訳が分からない状態になってしまう恐れが
ございます。

Excel-VBAは「『オブジェクト指向プログラミング』が可能な言語=複数のプロシージャを「部品のように」組み合わせるプログラムが作成可能な言語」ですので、以下のように組む方法をお勧めします。

Excel

1 2Sub Sample1() 3 処理1 4END Sub 5 6Sub Sample2() 7 処理2 8End Sub

と作成し、「Sample1→Sample2」のように実行したいときは、

Excel

1Sub Sample3() 2 '呼び出すプロシージャ名の()は不要 3 Call Sample1 4 Call Sample2 5 6End Sub

と、「Call」を使ってプロシージャを追加すると、プロシージャの改良や追加が楽になり、
エラーも起きにくくなりますよ?
(FunctionはCallを使わないこと。)

あるいは、このようにしても大丈夫です。

Excel

1Sub Sample1() 2 処理1 3 4 Call Sample2 5 6END Sub

老婆心ながら、という事で。

あと、「最後の行だけ改行を入れない」というのであれば、

  1. jawa様の「メイン2」の変数「strOutput」を「動的配列」にする。
  2. 配列の最大インデックス番号に格納されたデータのみvbCrlfを入れないように条件を分ける

このように言われても「??」だとは思いますが…。
もし分からない場合は、コメント等でお尋ねください。

頑張って!

投稿2016/11/22 11:31

編集2016/11/25 04:46
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ryuujinn

2016/11/23 04:54

tmkey01さん、コメント、コード記載ありがとうございます 記述して頂きましたコードを実行してみたのですが 「コンパイルエラー: ユーザ定義型は定義されていません。」とでてしまいました
退会済みユーザー

退会済みユーザー

2016/11/23 05:32

ryuujinn様  もしかするとですが、Excelのバージョン違い(当方はExcel2016)か、あるいは プログラムコメントの「参照設定」を行なっていないか、が原因と思われます。  プログラムコメントの「Regular Expressons 5.5」が、参照設定に 存在するかを確認し、チェックが入っていない場合はチェックを入れてから 実行してみてください。 (後ろの数字が低い場合は、1.0より大きいものにチェックを入れてみてください。)
ryuujinn

2016/11/24 04:59

tmkey01さん、コメントありがとうございます 教えて頂きました設定を確認し、設定しなおしたら、エラー出なくなりました コードを実行し結果、概ね期待通りの結果になったのですが、 実行結果を秀丸などのテキストソフトに張り付けた結果、 Excelのセル内にはない「"」がなぜか、文字の最初と最後に「"」が入ってしまいます Excelのverは2016です
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問