結合セルの問題点は行の高さが自動設定されないこと
Excelで結合セルに文章を書くことがあります。表や説明文などが組み合わさった資料の場合には重宝する機能です。
ところがこの結合セルには難点があります。その一つが行の高さが自動設定されないことです。
結合していない状態のセルの場合、折り返し設定をしていれば文字数に合わせて行の高さが自動設定されます。
ところが結合セルの場合は行の高さを自動設定してくれず、はみ出している部分は表示から消えてしまいます。
VBAを使わない場合の解決方法は手作業しか無い
解決方法は1つしかありません。手で行の高さを変えるしかありません。
結合していないセルであれば、行の線をダブルクリックすると適切な高さに自動設定されますが結合セルにはそれも使えません。結局は手で行の高さの数値を入力するか、行の高さの線をドラッグして移動させるかの手作業の方法しかありません。
しかも、いずれの場合も完全に手動でやるしかないため、自動設定された場合と同じ高さにしたい場合や印刷範囲が気になる場合には、事前に自動設定した場合の高さを調べてそれを入力するか手で高さの線をそこまで移動させるかしかなく、とても手間がかかることになります。
はい、いやです。めんどくさいです。VBAで対応しましょう。
マクロの処理概要
以下のマクロはそういう不便な結合セルの高さを自動設定するものです。複数の結合セルを選択して実行することも可能です。
一般的には横に結合したセルが多いため、主に横結合したセルを対象としたマクロですが、縦に結合したセルでも利用できます。もちろん、結合していない普通のセルの高さも自動設定します。
処理の概要は以下の流れになります。
- 結合セルの列幅を記憶する。
- セルの結合を解除する。
- 解除後のセルの列幅を、結合時の列幅に変更する。
- 通常セルの状態になっているため、自動設定して行の高さを適切なサイズに設定する。
- 自動設定された行の高さを記憶する。
- 再度セル結合を行い、記憶していた行の高さを再度設定する。
印刷対応は通常のExcelと同様で、大体の場合は出来てます
Excelでは画面ではちゃんと全部の文字が表示されていたのに印刷時に切れてしまうバグがあります。
この自動調整マクロを実行した場合はどうなるかというと、印刷したらちゃんと全部の文字が表示されるのかが心配になりますが、大体表示されます。
大体、というのはExcelの仕様通り、という意味で、もしちゃんと印刷されない場合はマクロの使用するしないに関わらず、それ以前に結合セルでない普通のセルでもちゃんと印刷されません。
これはExcelのバグもそのままこのマクロに取り込まれているためで、そこはご了承ください。
同じ行に別の結合セルがあった場合
このマクロには認識はしているのですが入れていない処理があります。それは、同じ行に結合セルが他にもあった場合、そちらの行の高さを無視して設定してしまう点です。
実は、このマクロを思いついたときは同じ行の他の結合セルのチェック処理は入れるつもりでした。しかし実際に使ってみると、チェック処理がなくても全く不便なことがなく、自分で使う分には「他に結合セルがあるか目で見れば分かるからいいや」と思い、チェック処理を入れませんでした。知人にも使ってもらい、チェック処理について聞いてみましたが、「いや、いらんくね? 十分じゃね? 見りゃわかるし」とのことでした。
同じ行の他の結合セルのチェック処理を入れてもいいのですが、多くの場合はそのチェック処理は無用の処理になるため処理時間が掛かることの欠点の方が多いと感じたのもあります。
普通に使う分には問題ないと思います。実際私も問題なく利用できています。ごくまれに他の列に結合セルがある場合があるのですが、すぐに気が付きます。
他の列に結合セルがあった場合は、そちらでもこのマクロを実行すればすぐにどちらの高さを選択すればいいのかが分かります。
ソースコード
以下がコードになります。
関数が5つありますが、1つ目の関数が実行する関数になります。
残り4つは内部で呼び出される関数です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
Sub 結合セルの行高さ自動設定() Dim r As Range Dim iBondWidth '// 結合時のセル幅 Dim iStartCellWidth '// 処理対象セルの幅 Dim sBeforeAddress '// 結合時の結合対象セル Dim iBeforeHeight '// 最終的に設定する高さ Dim sArCell() As String '// セル範囲 Dim bRet As Boolean '// 戻り値 Dim i '// ループカウンタ Dim iArCount '// 配列要素数 Dim sNowAddress '// 現在セル座標 Dim bExistFlg As Boolean '// 配列内にセルが存在しているか判定フラグ(True:存在する、False:存在しない) Dim iArRow() '// 複数行の結合時の各行の高さ ReDim sArCell(0) Application.ScreenUpdating = False For Each r In Selection '// 結合時の幅を取得 iBondWidth = 結合セルの幅(r) '// 結合時の各セルの高さを取得 Call 結合セルの高さを取得(r, iArRow) iArCount = UBound(sArCell) '// セル配列内に現ループのセルがあれば処理対象。そうでなければ次のSelection処理なので後続処理で配列取り直し。 bExistFlg = False sNowAddress = r.Address(False, False) For i = 0 To iArCount If (sNowAddress = sArCell(i)) Then bExistFlg = True Exit For End If Next '// 配列内に現ループのセルがない場合(結合セルがループで変わった場合) If (bExistFlg = False) Then '// セル範囲の全セルを配列で取得 bRet = セル範囲の各セル座標を取得(r, sArCell) End If '// 結合セルの場合 If (sNowAddress = sArCell(0)) Then iStartCellWidth = r.ColumnWidth '// 結合時の結合対象セルを取得 sBeforeAddress = r.MergeArea.Address(False, False, ReferenceStyle:=xlA1) '// 結合を解除 r.UnMerge '// 結合時のセル幅まで拡張する r.ColumnWidth = iBondWidth '// 折り返しON r.WrapText = True '// 必要な高さを取得 r.EntireRow.AutoFit '// セル高さを取得 iBeforeHeight = r.RowHeight '// 再結合 Range(sBeforeAddress).Merge '// 結合後のセルを元のセル幅に戻す r.MergeArea.Item(1).ColumnWidth = iStartCellWidth '// 結合後のセルの高さを設定 Call 結合セルの高さを設定(r, iBeforeHeight, iArRow) End If Next Application.ScreenUpdating = True End Sub Public Sub 結合セルの高さを取得(a_rRange As Range, a_iArRow()) Dim iRowCount Dim i ReDim a_iArRow(0) iRowCount = a_rRange.MergeArea.Rows.Count For i = 1 To iRowCount ReDim Preserve a_iArRow(i - 1) a_iArRow(i - 1) = a_rRange.MergeArea.Rows(i).RowHeight Next End Sub Public Function 結合セルの幅(a_rRange As Range) Dim iColCount Dim i Dim iWidth iColCount = a_rRange.MergeArea.Columns.Count iWidth = 0 For i = 1 To iColCount iWidth = iWidth + a_rRange.MergeArea.Item(i).ColumnWidth Next 結合セルの幅 = iWidth End Function Function セル範囲の各セル座標を取得(a_rRange As Range, a_sArCell() As String) As Boolean Dim sAddress '// セル位置 Dim v Dim sStartCell Dim sEndCell Dim iMergeCount Dim i '// セル範囲取得 sAddress = a_rRange.MergeArea.Address(False, False, ReferenceStyle:=xlA1) iMergeCount = a_rRange.MergeArea.Count For i = 0 To iMergeCount - 1 ReDim Preserve a_sArCell(i) '// Itemは1スタート a_sArCell(i) = a_rRange.MergeArea.Item(i + 1).Address(False, False, ReferenceStyle:=xlA1) Next セル範囲の各セル座標を取得 = True End Function Public Sub 結合セルの高さを設定(a_rRange As Range, a_iBeforeHeight, a_iArRow()) Dim iSumRow Dim i Dim iCount Dim iFirstRow Dim iRemainRow iSumRow = 0 iCount = UBound(a_iArRow) '// 単一行の場合 If (iCount = 0) Then a_rRange.RowHeight = a_iBeforeHeight Exit Sub End If '// 以下複数行の場合 For i = 0 To iCount iSumRow = iSumRow + a_iArRow(i) Next '// 先頭行の高さ iFirstRow = a_iArRow(0) '// 残りの行の高さ iRemainRow = iSumRow - iFirstRow '// 結合時の高さが元の高さより高い場合 If (a_iBeforeHeight > iSumRow) Then a_rRange.RowHeight = a_iBeforeHeight - iRemainRow Else a_rRange.RowHeight = iFirstRow End If End Sub |
マクロの使い方
縦の結合
縦に結合したセルに文字を入力します。
以下の例では文字数がセル幅より長いのですが、高さの自動調整が行われず文字が途中で切れています。
文字を入力後、結合セルを選択して上記マクロ「結合セルの行高さ自動設定()」を実行します。実行後、高さが自動的に調整されます。
選択している複数行のうち、先頭行の高さが調整されます。残りの行の高さは変わりません。
横の結合
横に結合したセルに文字を入力します。
縦の場合と同様、文字が途中で切れています。
上記「結合セルの行高さ自動設定()」を実行後、高さが自動調整されます。
是非活用してください。
たまにある問い合わせ
上のマクロでは縦に結合したセルの1番上のセルだけの高さを調整しているため、たまに、「2番目のセルの高さを調整できませんか」とか「一番下のセルの高さを調整できませんか」とか「結合したセルすべてを同じ高さにできませんか」とかの問い合わせがあります。
以前は個別に対応してましたが、対応しないことにしました。
それぞれ要望が微妙に異なり、使う人によってやりたいことが結構違うようで、時間がとられまくりで対応しないことにしました。