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

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

ただいまの
回答率

90.50%

  • VBA

    2315questions

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

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 767

onionion

score 5

 前提・実現したいこと

上からずらっと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での環境です。
シート名には実務で使用する際に使うブックのシートの名前が入ります。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2018/08/09 22:02

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

    キャンセル

  • onionion

    2018/08/17 12:25

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

    キャンセル

回答 3

checkベストアンサー

+1

ども。

やりたいことは、
「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)プログラム終わり

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

Sub Macro1()
'
' Macro1 Macro
'

'
    Range("B6").Select
    ActiveWindow.View = xlPageBreakPreview
    Range("A1").Select
    ActiveCell.FormulaR1C1 = "1"
    Range("A1").Select
    Selection.AutoFill Destination:=Range("A1:A37"), Type:=xlFillDefault
    Range("A1:A37").Select
    Range("A9").Select
    ActiveWindow.SelectedSheets.HPageBreaks.Add Before:=ActiveCell
    Range("A21").Select
    ActiveWindow.SelectedSheets.HPageBreaks.Add Before:=ActiveCell
    Range("A30").Select
    ActiveSheet.ResetAllPageBreaks
End Sub


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

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

'0)プログラム始め
Sub test()
    Dim i As Long

    '1)シート上の改ページを解除する
    ActiveSheet.ResetAllPageBreaks
    '行番号の初期値を設定
    i = 4
    '2)対象のセルの上のセルが空白でない間、繰り返す
    Do While Cells(i - 1, "K").Value <> Empty
        With Cells(i, "K")
            '3)見ているセルの値とその上の値と比べて、違っていたら
            If .Value <> .Offset(-1).Value Then
                '改ページを挿入する
                ActiveSheet.HPageBreaks.Add Before:=.Cells
            End If
        End With
        '次の行番号を用意
        i = i + 1
        '4)2に戻る
    Loop
    '5)プログラム終わり
End Sub

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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

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

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

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

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

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

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/17 12:30

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

    キャンセル

+1

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

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

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

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

sub 改ページ()

Dim i As Long
Dim SaveKey As String

'すべての改ページを削除
Worksheets("シート名").ResetAllPageBreaks

'1~2行目をタイトル行に設定
Application.PrintCommunication = False
With Worksheets("シート名").PageSetup
.PrintTitleRows = "$1:$2"
.PrintTitleColumns = ""
End With

i = 3
SaveKey = CStr(Cells(i, 11).Value)

'K列の値が空白になるまでループ
Do Until Len(CStr(Cells(i, 11).Value)) = 0

'キーが変わったかどうかをチェック
If SaveKey <> CStr(Cells(i, 11).Value) Then
'改ページを挿入
Worksheets("シート名").HPageBreaks.Add Before:=Cells(i, 1)
'キーを更新
SaveKey = CStr(Cells(i, 11).Value)
End If
i = i + 1
Loop

'印刷プレビューを表示
Worksheets("シート名").PrintPreview

End sub 


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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/17 12:28

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

    キャンセル

  • 2018/08/17 12:39

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

    キャンセル

同じタグがついた質問を見る

  • VBA

    2315questions

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