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

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

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

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

Q&A

解決済

3回答

647閲覧

複数行にまたがる大中小見出しを統合するプログラム

zorac

総合スコア42

VBA

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

0グッド

0クリップ

投稿2017/08/19 15:19

###前提・実現したいこと
添付画像のような大中小の見出しが複数行に渡って構成されているExcelファイルがあります。
このファイルは外部から頂くものなので、ファイルの仕様を改める事は出来ません。
このままでは扱いづらいため、Excel VBAで添付ファイルのように1行にまとまった見出しに変更したいと思っています。
後工程まで全て自動化したいと考えている為、手作業ではなくVBAで処理したいと考えています。

###発生している問題・エラーメッセージ
イメージ説明

###試したこと
コーディング前の検討段階です。
大見出しが何セルに渡って結合されているのか調べ、中見出しと統合。
同じ手順で中見出しと小見出しを統合していくという流れでいくしかないかと考えていますが、
何かもっと上手い方法はありませんか。
こういったファイルが十数個あるので、なるべく工数の少ないアプローチを探しています。

同じような見出し構成のファイルが複数ありますが、それぞれ見出しの大きさが異なる為、
なるべく汎用的なコードのサンプルがあればそれを利用したいと思っています。
ネットを検索してみましたが、自分では見つけられなかったので、もしご存知であれば教えて下さい。
サンプルがなければアプローチの仕方だけでも良いのでアイデアを頂ければと思います。
宜しくお願いします。

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

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

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

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

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

momon-ga

2017/08/19 15:58

セルの結合のチェックや、結合セルの範囲確認のサンプルが、いろいろ見つかると思いますが、具体的に知りたいことを追記してください。
zorac

2017/08/20 14:48

特定の機能の使い方が分からないという事ではなく、よりシンプルなアルゴリズムを知りたいという主旨の質問でした。今後はもう少し意図が伝わりやすいよう文面を考えて質問するようにします。ありがとうございます。
guest

回答3

0

ベストアンサー

MergeArea で結合セルの範囲(range)を取得できます。
MergeArea(1, 1) で結合セルに表示される値を取得できます。
これを使って汎用的な関数を作成してみました。

Public Sub HeaderMerge(WS As Worksheet) Dim i As Long, R As Range With WS For i = 1 To .Cells(1, 1).CurrentRegion.Columns.Count Set R = .Cells(3, i) If R <> "" Then R = R.Offset(-2).MergeArea(1, 1) & "/" & _ R.Offset(-1).MergeArea(1, 1) & "/" & _ R ElseIf R.MergeArea.Rows.Count = 2 Then R.UnMerge R = R.Offset(-2).MergeArea(1, 1) & "/" & _ R.Offset(-1) ElseIf R.MergeArea.Rows.Count = 3 Then R.UnMerge R = R.Offset(-2).MergeArea(1, 1) End If Next .Range("1:2").Delete End With End Sub '使用例 Sub Test() Call HeaderMerge(Sheet1) End Sub

投稿2017/08/19 17:57

編集2017/08/19 18:15
hatena19

総合スコア33699

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

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

zorac

2017/08/20 14:46

>MergeArea(1, 1) で結合セルに表示される値を取得できます。 この知識はこの先ずっと役に立つに違いなく、大変参考になりました。 コンパクトで理解し易く、その上汎用的なサンプルコードまで提示して頂き、ありがとうございました。
guest

0

例えば、中見出しがB2:B6セルで結合されている場合、実際に値を取得出来るのはB2セルですので
小見出しを順に処理していって、一つ上のセルに値が無い場合、その更に左のセルを探索することを繰り返すことで、中見出しの値が取得できます。

例えば、C3の一つ上のセルは

Cells(3,3).Offset(-1)

で取得できます(C2)。

「値を取得できるまで、その左のセルを探索する」というのは
例えば下記のような関数で実現できます。

Function getValue(c As Range) If c.Value = "" Then getValue = getValue(c.Offset(, -1)) Else getValue = c.Value End If End Function

C2から始めて、A2まで探索するには

getValue(cells(2,3))

のようにします。

あとは、このgetValueの戻り値を使って、小見出しの値を変更するなどすると良いでしょう。

投稿2017/08/19 17:10

編集2017/08/19 17:11
tsuemura

総合スコア663

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

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

zorac

2017/08/20 14:39

小見出しから見ていく方が処理はしやすいですね。 上から順に見ていくことしか考えていませんでした。 大変参考になりました。ありがとうございました。
guest

0

同じ手順で中見出しと小見出しを統合していくという流れでいくしかないかと考えていますが、何かもっと上手い方法はありませんか。

手っ取り早いのは、

  1. 別シートに最終形態のシート+リンク付きのセルを作り、それをつかってデータ更新
  2. 上から3行目のインデックス修正 + 上から2行のデータを削除

いずれも結合云々の操作なしです。
こんな感じででよいのでしょうか?

投稿2017/08/19 16:25

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

zorac

2017/08/20 14:34

保守性の観点から作業用のシートはあまり設けたくないので、今回は全てVBAでやってしまおうと考えています。 ですが、なんでもかんでもコーディングせずに、Excelの標準機能で補えるところは上手く活用すべきだと改めて思いました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問