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

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

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

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

Q&A

解決済

3回答

1562閲覧

VBA 値が変更された際に改行をするプログラムを作成したい

onionion

総合スコア13

VBA

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

0グッド

0クリップ

投稿2018/08/09 13:00

編集2018/08/17 03:31

前提・実現したいこと

上からずらっと10000行ぐらいあるデータを保管しているエクセルがあります。(2行目まではタイトル) K列(11行目)の値(文字です)が変更されたとき、変更された場所で改ページを 挿入するマクロを作成したいのですが、下記のマクロで対応すると改ページが挿入されたり されなかったり、理由も不明で困っています。 そこで ①このマクロでなぜ改行が挿入されない時が存在するのかどうかを教えてください。

②改良できる場所があれば教えてください。

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

エラーはありません。改行がされません

該当のソースコード

vba sub 改ページ() Dim i As Long Dim SaveKey As Variant 'すべての改ページを削除 Worksheets("シート名").ResetAllPageBreaks '1~2行目をタイトル行に設定 Application.PrintCommunication = False With Worksheets("シート名").PageSetup .PrintTitleRows = "$1:$2" .PrintTitleColumns = "" End With i = 3 SaveKey = Cells(i, 11).Value 'K列の値が空白になるまでループ Do Until Len(Cells(i, 11).Value) = 0 'キーが変わったかどうかをチェック If SaveKey <> Cells(i, 11).Value Then '改ページを挿入 Worksheets("シート名").HPageBreaks.Add Before:=Cells(i, 1) 'キーを更新 SaveKey = Cells(i, 11).Value End If i = i + 1 Loop '印刷プレビューを表示 Worksheets("シート名").PrintPreview End sub

補足情報(FW/ツールのバージョンなど)

Windows7 32bit Excel2010での環境です。 シート名には実務で使用する際に使うブックのシートの名前が入ります。

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

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

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

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

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

m.ts10806

2018/08/09 13:02

コードは```で「囲う」必要があります(末尾は改行を入れてください) うまくいっているかはPCであればプレビューがリアルタイムで表示されるのでそちらを確認しながら調整して投稿してください。
onionion

2018/08/17 03:25

ご連絡が遅くなり大変失礼いたしました。修正しました。ご指摘、ありがとうございました。
guest

回答3

0

ベストアンサー

ども。

やりたいことは、
「K列のデータを上から順に見て行って、見てるセルの値が、その上のセルの値と違っていたら、改ページを挿入したい。」
ということですよね?

「値が変更された際に改行をするプログラムを作成したい」

「値が変更された際に」と言われると、
「いま、まさに対象のセルの値が変更された」その時と解釈されます。
そして、改行ではなく改ページですよね?
エクセル君は一字一句でも間違えると、期待した答えを返してくれません。
人間だと、文脈とかから類推して言いたいことを推測しちゃうんですが^^;

上手くいかなくて混乱してたり、時間がなくて焦って書いたり、
変な文言を使ったのかも知れませんが、この辺をちゃんと間違わないで、
説明できるようにならないと、プログラムも書けるようになりません。

さて、ちょっと①のなんで?って疑問は、同じデータで同じマクロを動かしてみないとわかりませんが、こういうのは自分で間違いを見つけられるようにならないといけません。
VBAを書くツールでVBEを使っていると思いますが、このツールは、
間違いを見つけるために、一行毎にプログラムを実行できる機能が付いています。

https://asatte.biz/vba-debug-menu/

こういうことをすれば間違いを見つけられるかも知れません。
(今回の件で見つかるかどうかは不明)
今回の件で言うと、

「改ページが挿入されたりされなかったり」

ということは、

If SaveKey <> Cells(i, 11).Value Then

のところで意図した判定が行われてないと想像できます。
なので、ステップ実行しながら、比較している値が、
どんな値かいちいちチェックして、どうなりたいけど、
どうなっているかを確認してみたらいいと思います。
特に、英数の半角・全角の違いは画面上でみてもよくわからないので、
その辺は注意してみてみるといいでしょう。
他には記号系も似ているけど違うなんてこともあるので、
(例えば、〇と○とかエクセル上では違いが分かり難い?)
注意しましょう。
もし、どうしても解らなくて、他人にデバッグを頼みたいのならば、
マクロのコードだけでなく、同じデータで動作確認するひつようがあります。
今回の場合はK列のデータ?
その辺をも少し落ち着いて確認されたり、説明されたりするといいと思います。

提示のコードのデバッグはご自分でされるとして、
もう一度やりたいことを、整理してみましょう。

0)プログラム始め
1)シート上の改ページを解除する
2)K3から下にデータが無くなるまで見て行く
3)見ているセルの値とその下(またはその上?)の値と比べて、
違っていたら改ページを挿入する
4)2に戻る
5)プログラム終わり

こうなると思います。
ここで、コードを書く前にエクセル君の癖と必要なコードを、
「マクロの記録」という機能を用いて探ってみます。

VBA

1Sub Macro1() 2' 3' Macro1 Macro 4' 5 6' 7 Range("B6").Select 8 ActiveWindow.View = xlPageBreakPreview 9 Range("A1").Select 10 ActiveCell.FormulaR1C1 = "1" 11 Range("A1").Select 12 Selection.AutoFill Destination:=Range("A1:A37"), Type:=xlFillDefault 13 Range("A1:A37").Select 14 Range("A9").Select 15 ActiveWindow.SelectedSheets.HPageBreaks.Add Before:=ActiveCell 16 Range("A21").Select 17 ActiveWindow.SelectedSheets.HPageBreaks.Add Before:=ActiveCell 18 Range("A30").Select 19 ActiveSheet.ResetAllPageBreaks 20End Sub

行った操作と記録されたコードを見て、さらに、ヘルプも確認します。
http://www.ken3.org/vba/excel-help.html

結果、指定したセルの上に改ページが挿入されるので、
K4から見て行って、見ているセルの1個上が空白になるまで繰り返すように
書いてみます。

VBA

1'0)プログラム始め 2Sub test() 3 Dim i As Long 4 5 '1)シート上の改ページを解除する 6 ActiveSheet.ResetAllPageBreaks 7 '行番号の初期値を設定 8 i = 4 9 '2)対象のセルの上のセルが空白でない間、繰り返す 10 Do While Cells(i - 1, "K").Value <> Empty 11 With Cells(i, "K") 12 '3)見ているセルの値とその上の値と比べて、違っていたら 13 If .Value <> .Offset(-1).Value Then 14 '改ページを挿入する 15 ActiveSheet.HPageBreaks.Add Before:=.Cells 16 End If 17 End With 18 '次の行番号を用意 19 i = i + 1 20 '4)2に戻る 21 Loop 22 '5)プログラム終わり 23End Sub

②改良できる場所があれば教えてください。

そもそも、
「小計」機能に改ページを付ける機能が付いているので、
小計機能でデータの件数でも数えてやれば、
マクロなんて必要ないうえに先に書いたコードよりも速く処理できます。
どうしても、数式が不要な場合は、
ジャンプ機能で挿入された数式を検索して、行削除してやるといいと思います。
もし、他にも数式が入っているという事なら、
データ中の空白をジャンプ機能で検索するとかしたらいいと思います。
それもだめなら、検索とか置換とかフィルターも合わせて何か方策を探って、
解決していけばいいと思います。
そして、手順が複雑になったら、その時に操作の自動化(=マクロ化)を
考えて行ったらいいと思います。
操作手順が明らかになっているなら、それをマクロの記録してみて、
記録されたマクロをブラッシュアップして汎用的に使えるように、
改良したらいいと思います。

投稿2018/08/18 12:55

mattuwan

総合スコア2136

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

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

0

質問者さんのやりたいことは、
「K列の文字列が上下のセルで切り替わる前後で改ページを入れる」
ということだと思われます。
本文の説明ではセルに文字を打ち込んだ時と誤解しますね。

で、ソースを見ても懸念の現象が発生するとは思えません。
逆に意図しない箇所で改ページが入る可能性はあります。

提示の方法だと"文字列としての数字"と"数値としての数字"が区別されるので、数字の1と文字の"1"が連続する箇所で改ページが入ってしまいます。
K列全部文字列書式に変更すればOKと思いがちですが、書式で変更したつもりでも、次にセルを編集するまで変更前の型で保持しているので書式は文字列だけど実際は数値という状態が発生します。

それを踏まえると、セルの内容は毎回Stringに変換するとよいと思います。

VBA

1sub 改ページ() 2 3Dim i As Long 4Dim SaveKey As String 5 6'すべての改ページを削除 7Worksheets("シート名").ResetAllPageBreaks 8 9'1~2行目をタイトル行に設定 10Application.PrintCommunication = False 11With Worksheets("シート名").PageSetup 12.PrintTitleRows = "$1:$2" 13.PrintTitleColumns = "" 14End With 15 16i = 3 17SaveKey = CStr(Cells(i, 11).Value) 18 19'K列の値が空白になるまでループ 20Do Until Len(CStr(Cells(i, 11).Value)) = 0 21 22'キーが変わったかどうかをチェック 23If SaveKey <> CStr(Cells(i, 11).Value) Then 24'改ページを挿入 25Worksheets("シート名").HPageBreaks.Add Before:=Cells(i, 1) 26'キーを更新 27SaveKey = CStr(Cells(i, 11).Value) 28End If 29i = i + 1 30Loop 31 32'印刷プレビューを表示 33Worksheets("シート名").PrintPreview 34 35End sub

SaveKeyをString型に変更、セルのデータはCStr関数で文字列に変換しています。

で、「改ページが挿入されない場合」ですが、質問文からは読み取れません。
どんなデータが入ったときに改ページが挿入されないか、具体例を提示できれば良い回答が付くかもしれません。
具体例の補足をお願いします。

投稿2018/08/10 11:13

hope_mucci

総合スコア4447

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

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

onionion

2018/08/17 03:28

せっかくご回答いただいたにもかかわらず、ご連絡が遅くなり大変失礼いたしました。 書式の問題についてご指摘いただきありがとうございます。 上記のコードを実行してもダメでした。 もしかすると表が横にも長いから? そんなことってありますかね。
hope_mucci

2018/08/17 03:39

いや、どんな条件で改ページが挿入されないのか具体例を出せって書いたのに読んでくれてないんですか? 出せないのなら誰も問題点は分からないですよ。横幅が原因と思うならKから右を消してやって見れば分かることじゃない?
guest

0

掲載コードは、ざっくりまとめると

K列の値を4行目から下に向かって値が空になるまで、1つ上の行のK列の値と比較し、異なっていた場合に改ページする

という内容になっています。ためしに手元のEXCELで動かしてみましたが、

改ページが挿入されたり、されなかったり

の状態は、確認できませんでした。書かれたコードの通りに正しく動作していると思います。

で、次に、質問文に書いてある「やりたいこと」ですが

K列(11行目)の値(文字です)が変更されたとき、変更された場所で改ページ

これを、読んだ通りにそのまま解釈できる内容が要望なのであれば、
掲載コードは全体に置いて、その要望を満たせていません。

変更されたに処理をするなら、Worksheet_Changeあたりを使って実装するのがポピュラーかな?と思いますし、
変更されたかを判断するには、変更前の値今の値を比較する必要があると思います。(比較対象は「上の行の値」ではないはず。。)

実際に「何が正しいのか」は、私たち回答者には判断ができませんので、ご自身でよく確認してみてください。

投稿2018/08/10 02:55

mix-peach

総合スコア1910

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

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

onionion

2018/08/17 03:30

せっかくご回答いただいたにもかかわらず、ご連絡が遅くなり大変失礼いたしました。 「K列の文字列が上下のセルで切り替わる前後で改ページを入れる」、hope_mucci 様がご指摘いただいた通りでございます。 本来、K列には地名(●●市、みたいな)が入っており、 印刷する際にある程度の地域ごとに分けられるような仕組みを作りたかったのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問