• ベストアンサー

ExcelVBA 列の幅に収まらない文字列を下へ

お世話になります。 セル書式の折り返し・縮小・結合を使用しないで、 列の幅に収まらない文字列を下の行のセルへ表示させる方法を模索しています。 Application.DisplayAlerts = False Range("A1").Justify で出来るらしいと書物を頼りに実施していますが、下の行のセルへ表示出来ません。 他の方法も含めて、実現方法はあるでしょうか? よろしくお願いします。

  • tt246
  • お礼率91% (116/127)

質問者が選んだベストアンサー

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは。 .Justify メソッド 私は、昔に少し試したぐらいで詳しいわけではないです。 今、私の環境(Win7 XL2010 64)では、正しく処理できる方法が 解らないでいます。はっきりしなくてすみません。 「単語とスペースで構成された平易な英文」 「全角文字の連続」 などでは機能するようですが、 「abcdefghijklmnopqrstuvwxyz」 「a1234567890」 などでは機能しないようです(機能させる方法が見つかりません)。 また、およそ255文字を超える分は無くなってしまう、そもそもの仕様のようです。 なので、とりあえず、 「折り返して全体を表示する」の動作を元にして、 "下の行のセル"へセルを分割できるものを書いてみました。 (外部オブジェクトを使う方法もありそうですが、、、。) 「折り返して全体を表示する」の仕様で、 たぶん1024文字を超えると正しく機能しないのでしょうけれど、 セルが文字列値であれば他に制約はないと思います。 数式(関数)を設定してあるセルを指定すると、 戻り値が文字列なら、数式を値に換えて処理します。 そもそも数式に対して折り返しもJustifyも関係ない訳ですが、 思わぬ結果にならない様に留意して、運用してください。 修正、調整に困るようでしたら、補足欄にでも書いてみてください。 ' ' 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 ' ' ※複数列を対象にした処理は想定(対応)しない ' ' ※サブルーチンの引数はRange型で、必ず単セル ' ' サンプルは ' ' COL = 1、 →「A列の」 ' ' TOPROW = 1 →「1行目から」...「有意な最下行まで」 ' ' With Sheets("Sheet1") → 「Sheet1 を対象に」 ' ' 処理するように指定した例示です。 Sub Re8105487main() ' サンプル   Const COL = 1 ' 処理対象 列 位置 指定   Const TOPROW = 1 ' 先頭行 位置 指定   Dim i As Long   Application.ScreenUpdating = False   With Sheets("Sheet1") ' 処理対象 シート 指定 Sheet2.Cells.Copy .Cells(1) .Range("A:B").Cut .Cells(COL)     With .Range(.Cells(TOPROW, COL), .Cells(Rows.Count, COL).End(xlUp)) ' 処理対象 範囲 指定       For i = .Rows.Count To TOPROW Step -1 ' 下から上へ順に処理         Call Re8105487sub(.Cells(i, COL))       Next i     End With     Application.ScreenUpdating = True   End With End Sub ' ' ============================== Sub Re8105487sub(ByVal Target As Range) ' ' 「Targetは単一セルを指定する」「シートの保護はエラー」 ' ' 呼び出し側でエラー回避すること。   Dim sTemp ' As String ' 対象セルの文字列   Dim nPrevHeight As Long   Dim nRegHeight As Long   Dim nRatio As Long   Dim nLength As Long   Dim nRowPos As Long   With Target     .WrapText = False ' 折り返しを「確実にキャンセル」     nPrevHeight = .Height ' 実行前の行高を取得(確保)     .EntireRow.AutoFit ' 行高を標準化(フォント依存)     nRegHeight = .Height ' 標準の行高(フォント依存)を取得     .WrapText = True ' 「折り返して全体を表示する」     nRatio = .Height / nRegHeight ' 折り返し後の行高を標準の行高で割り算して行数を求める     sTemp = .Value ' セルの値を取得     If nRatio = 1 Or TypeName(sTemp) <> "String" Then ' 行を追加する必要が無ければ       .WrapText = False ' 折り返しをキャンセル       .RowHeight = nPrevHeight ' 行高を実行前に戻す       Exit Sub ' サブルーチンを抜ける     End If     .Offset(1).Resize(nRatio - 1).EntireRow.Insert ' 必要な行数だけ行挿入     nLength = Len(sTemp) ' 文字長を取得     For nRowPos = nRatio To 2 Step -1 ' 挿入した行を下から上にループ       Do         nLength = nLength - 1 ' 文字長を減らす         .Value = Left$(sTemp, nLength) ' セル値を一文字ずつ短くする       Loop Until CLng(.Height / nRegHeight) < nRowPos ' セルの折り返しによる行高が小さくなったら       .Cells(nRowPos, 1).Value = Mid$(sTemp, nLength + 1) ' 後方の文字列を挿入した行のセルに出力       sTemp = Left$(sTemp, nLength) ' 未出力の文字列     Next nRowPos     With .Resize(nRatio)       .WrapText = False ' 折り返しをキャンセル       .RowHeight = nPrevHeight ' 行高を実行前のものに統一 '      Target.Copy '      .PasteSpecial xlPasteFormats '      Application.CutCopyMode = False     End With   End With End Sub ' ' 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

tt246
質問者

お礼

ご丁寧に、プログラム付きでありがとうございます。 全てを理解するのは無理ですが、一部は取り入れられると思います。 さっそく応用してみます。

その他の回答 (1)

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.2

あ、すみません。 編集ミス、消し忘れがありました。 > Sheet2.Cells.Copy .Cells(1) > .Range("A:B").Cut .Cells(COL) 上記2行は、こちらでのテスト用の記述ですので、 削除して投稿するべきものでした。 上記2行、削除してください。 失礼しました。

関連するQ&A

  • B列の値を参照して、A列に連番を振る方法

    A・B・C列があり、A列には連番を、B列にはVLOOKUP関数が入っており、 C列には、B列の検索値が入っております。 B列は下記のVBAコードで同じ値をセル結合させています。 Sub 結合() Dim rngU As Range Dim i As Range Dim rngB As Range Dim Key As String Set rngB = Range("B2") Set rngU = Range(Range("B3") _ , Range("B6000").End(xlUp).Offset(1)) Application.DisplayAlerts = False For Each i In rngU If Not i.Text = Key Then If (Not i.Offset(-1) Is rngB) And _ (Not i Is rngB) Then Range(rngB, i.Offset(-1)).MergeCells = True End If Set rngB = i End If Key = i.Text Next i Application.DisplayAlerts = True End Sub そこで、A:3から連番を振りたいのですが、B列の決まった特定の結合セルの 隣のA列のセルもB列の決まった特定の結合セルと同数にセル結合させ、 連番を1つとしてカウントしたいのです。 また、A列にはB列同様にVLOOKUP関数が入っており、連番を振りたくないセルには 印が付くようにしています。 行数やB列の決まった特定の結合セル番地はランダムに変わるため、B列の結合セルで参照させるしか ないのかなっと思っております。 B列の特定の結合セルの値は決まっております。 上記のような処理を自動にさせるためのVBAが分かる方がいらっしゃいましたら、 是非ご教授お願いいたします。

  • 行幅をなくしたいのですが…

    行幅を0にするマクロを作成したのですが、セルが結合されているとそのセルの文字まで消えてしまいます。下のマクロは一度セル結合を解除して、その文字をコピーしたままセル幅を0にして、またセル結合してコピー貼り付けるようなやり方です。最後の3行は残しといて幅を合わしています。もっと良いやり方あれば教えてください。分かりずらいかもしれませんがお願いします。 又、元の幅に合わしたいマクロも教えていただければ助かります。   Range("A4:A14").Select Selection.UnMerge Range("A4").Select Selection.Copy Range("A12").Select ActiveSheet.Paste Rows("4:11").Select Selection.RowHeight = 0 Range("A12:A14").Select Application.CutCopyMode = False Selection.Merge Rows("12:14").Select Selection.RowHeight = 14.25

  • セル解除後、各行に値をコピーし結合するマクロ

    A1からC3のセルが結合しており、 そのセル結合を解除すると、A列のみ値がコピーされる。 コピーした後、各行ごとにセルを結合していく…… という処理をしたいと思い、 調べて下記のマクロまでなんとかこぎつけました。 Sub セル結合() Dim date1 As Variant Dim range1 As Range Application.DisplayAlerts = False For Each range1 In Selection.Rows If range1(1).MergeCells = False Then range1(1).Merge Else date1 = Selection.Rows(1).Value With range1 .UnMerge .WrapText = False .ShrinkToFit = False Selection.Value = date1 End With End If Next range1 End Sub ※実行範囲に関しては、  任意選択をした範囲にしたいため、  range(1)にて処理を行いました。 困っているのは、上記のマクロを実行すると、 最初の行のみ結合できないということ。 もうひとつが、 セル結合をしない時に値を左端にコピーすると、 文字が自動縮小されてしまいます。 縮小しないようにするには、 どのような処理を入れたら良いでしょうか? お力添え頂けますと幸いです。 よろしくおねがいします。

  • 最終列に入力されている文字を表示する

    エクセルVBAで最終列に入力されている値の表示方法について教えてください。 最終行については表示できるのですが、最終列に入力されているものの表示がうまくいきません。 A列の最終行の値をセル”D1”に表示するについては Private Sub Worksheet_Change(ByVal Target As Range) Dim r As Long r = Cells(Rows.Count, 1).End(xlUp).Row Range("D1").Value = Cells(r, 1).Value End Sub でうまくいきました。 最終行、例えば3列目の10行目に”111”と入力されているときにセル”D1”に”111”と表示するようにはどうしたらよいのでしょうか。 どなたがご指南ください宜しくお願いします。

  • 確認/警告メッセージのトラップ(エクセルVBA)

    複数の行、列からなるセル範囲に値設定しているとします。このセル範囲に対し、行もしくは、列単位でセルの結合を行うと、"選択範囲には複数のデータ値があります。1つのセルとして結合すると、選択したセル範囲にある最も左上端にあるデータのみが保持されます。・・・・”と表示され、”OK”、”キャンセル”ボタンが表示されます。この”OK”、”キャンセル”ボタンのトラップって出来ますか?(関数の戻り値のように) 別の言い方をすると、複数行、列に対して結合を行うと、一度”OK”ボタンを押しても、次の行列で結合を行おうとすると再びメッセージが表示されます。一度、”OK”を押すと次からメッセージが表示されない(トラップできれば、DisplayAlerts = Falseとできるのですが?)ように出来ますか?キャンセルが押された場合、エラー"実行時エラー1004"が発生しますが、明確にキャンセルボタンが押されたと判断する方法ってありますか? どなたか、詳しい方教えて頂けないでしょうか?宜しくお願い致します。

  • エクセルマクロでセルの結合をしたい

    エクセル2003です。 E列の値は昇順で並んでいます。 先頭E3行から下の行の値と比較し 同じ値の場合はセルを結合し 値が違う場合は結合しないで次の行を比較という処理を 最終行まで行いたいです。 (添付画像参照) 例えば E3-AA E4-BB E5-BB E6-CC E7-DD E8-EE E9-EE E10-EE E11-FF セルE4とE5を結合します セルE8とE9とE10を結合します。 次に結合した行と同じ行数のF列を結合します。 さらに結合した行と同じ行数のG列を結合します。 上記の場合 セルF4とF5を結合、 セルF8とF9とF10を結合します。 セルG4とG5を結合、 セルG8とG9とG10を結合します。 さらに結合した行と同じ行数のA列を結合します。 上記の場合 セルA4とA5を結合、 セルA8とA9とA10を結合します。 さらに結合したA列に数字を入力します A4とA5を結合したA4、A5セルには 2行を結合したので2と入力 セルA8とA9とA10を結合したA8、A9、A10セルには 3行を結合したので3と入力。 とりあえず、E列の結合を完成させてそのE列を 3行目から最終行までコピーして、 「形式を選択して貼付」の「書式」で 書式のみをF,G,A列にコピーすれば出来るのではと 以下の構文を作成しました。 セルの結合時は結合するセルの先頭の行の値が結合済セルの値に なるので最初にE列を結合していく時に A列に結合回数を記入しようと考えました。 ただ2行の結合は、A列に2と入力されたのですが 3行連結した時も2と入力されてしまったので改造しました。 テストデータでは期待しているようになったのですが 本番データでは結合される行が4行、5行等それ以上の行数が 結合する場合が有りこの構文ではなるべくしてなっているのですが 4行以上の行結合はA列の値はいずれも3になってしまいます。 (添付画像参照) どう修正すればいいか手段が考え付きません。 どのような方法がありますでしょうか? よろしくお願いします。 Sub セル結合2() '2013年10月25日 Dim 最終行 As Integer Dim 処理行 As Integer Dim 比較行 As Integer Dim 確認値 As Variant Dim 比較値 As Variant Dim 結合回数 Dim 戻行 Application.ScreenUpdating = False ThisWorkbook.Sheets("Sheet1").Select 最終行 = Cells(Rows.Count, 5).End(xlUp).Row 'F列の最終行を求めます。 Application.DisplayAlerts = False For 処理行 = 3 To 最終行 '3行目から最終行の前まで繰り返します。 比較行 = 処理行 + 1 '処理行の一つ下の行と比較します。→比較行とします。 確認値 = Cells(処理行, 5).MergeArea(1, 1).Value 'チェックする値を、確認値に代入します。 比較値 = Cells(比較行, 5) '比較する値を、比較値に代入します。 If 確認値 = 比較値 Then '値が同じかどうか Range(Cells(比較行, 5), Cells(処理行, 5)).MergeCells = True 結合回数 = Cells(処理行, 1) + 1 'セルを結合した回数 戻行 = 処理行 - 1 '処理行の1行上の行数を戻行とする Cells(処理行, 1) = 結合回数 '処理行のA列に結合回数を記入 Cells(比較行, 1) = 結合回数 '比較理行のA列に結合回数を記入 If Cells(処理行, 1) >= 3 Then 'もしも処理行のA列が3以上の場合 Cells(戻行, 1) = 結合回数 '戻り行のA列に結合回数をセット End If '同じでない場合は以下へ End If '同じでない場合は以下へ Next 処理行 Application.DisplayAlerts = True Application.ScreenUpdating = True Range(Cells(3, 5), Cells(最終行, 5)).Copy Range(Cells(3, 6), Cells(最終行, 6)).PasteSpecial Paste:=xlPasteFormats Range(Cells(3, 7), Cells(最終行, 7)).PasteSpecial Paste:=xlPasteFormats Range(Cells(3, 1), Cells(最終行, 1)).PasteSpecial Paste:=xlPasteFormats Application.CutCopyMode = False MsgBox "終了しました" End Sub

  • Excel文字列の結合に条件式を付けたい

    エクセルで複数セルの文字列を1つに結合する際、条件を満たすものだけを結合して表示することはできないでしょうか。 <添付画像の例> A2:E2のうち1行目に「1」が付いたものだけを結合させ、セルG2に「あうお」と表示させたい

  • VBAでセル内の文字列を一行にする方法

    ExcelのVBAで、セル内に折り返しで3行に書かれている文字列を、各文字列間に空白を1つ入れて、1行につなげるにはどうしたらいいですか

  • Excelマクロにて文字列連結

    現在Excelのマクロにて文字列の連結を行っているのですが、 繋いだ文字列を改行を付けて連結を行いたいです。 セルとセルの中の文字列を改行を付けて連結するにはどうしたらいいのでしょうか? 例 A1セル「あああ」 B1セル「いいい」 C1セル「あああ       いいい」 Worksheets(sheet1).Range("C1").Value = Worksheets(sheet1).Range("A1").Value + Worksheets(sheet1).Range("B1").Value をすると 「あああいいい」と1行で表示されてしまいます。     ↑ ここに改行を入れるにはどうしたらいいのでしょうか? 以上、宜しくお願いします。

  • 行方向の同じ値のセルを結合するマクロ

    ネットで色々調べながら、A列方向の同じ値のセルを結合させるマクロ を作ってみたのですが、もっと簡単にできるようでしたら教えていただきたいです。 どうぞよろしくお願いいたします。 Sub セル結合() Dim r As Integer '行数 Dim i As Integer 'カウンタ r = Sheets(1).Range("a1").CurrentRegion.Rows.Count - 1 Application.DisplayAlerts = False For i = 1 To r Cells(i, 1).Activate '項目の一つ下のセルをアクティブに If ActiveCell.Value = ActiveCell.Offset(1).Value Then Range(ActiveCell, ActiveCell.Offset(1)).Merge End If Next Application.DisplayAlerts = True End Sub

専門家に質問してみよう