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

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

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

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

Q&A

解決済

4回答

924閲覧

For ~ Next 繰返し処理の最後で意図しない値を得てしまいます。

vitabrevisarsl1

総合スコア57

VBA

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

0グッド

0クリップ

投稿2017/10/26 01:26

編集2017/10/26 05:09

VBA

1 Dim p As Integer 2 Dim yearF As Integer 3p = 3 4 Worksheets("list").Select 5 For p = 3 To WorksheetFunction.CountA(Range(Range("f3"), Cells(Rows.Count, 6).End(xlUp))) + 2 6 yearF = Range("f" & p).Value 7    Debug.Print "F:" & p & " , " & yearF 8 If WorksheetFunction.CountIf(Worksheets("年間集計").Range("7:7"), yearF) = 0 Then 9 With Worksheets("年間集計").Range("e7:e" & Cells(Rows.Count, 5).End(xlUp).Row) 10 .Copy 11 .Insert xlShiftToRight, copyorigin:=xlFormatFromRightOrBelow 12 .PasteSpecial Paste:=xlPasteColumnWidths 13 .PasteSpecial Paste:=xlPasteFormats 14 End With 15 Worksheets("年間集計").Range("e7").Value = yearF '?1つだけ空になる■ 16 End If 17 Next p

「list」シートからyearFを上から繰返し読込しています。
イメージ説明

最後F5の際、p=5になっているのになぜかyearF=0となり、結果西暦年が0の列ができてしまします。
イメージ説明

デバッグでF8ステップ実行しても結果は変わりません。

お知恵を拝借できますと幸いです。

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

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

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

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

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

yuki-saito

2017/10/26 02:07

回答しようと色々読んで察そうとしてみたのですが、添付してくださっている画像に列番号(Fなど)や行番号がないので分かりませんでした。そこが分かるようにしてもられば何かお答えできるかもしれません。
guest

回答4

0

直接原因かどうか分かりませんが、
セルへアクセス(Range,Cells等)する際に、
Range("") や Cells(1 ,2) 等と親(Sheet)を省略すると、
自動的にActiveSheet上のセルが適用されます。

ご提示のコードを見るに、幾つか親が省略されてますので、
デバッグ時や、処理時にActiveSheetが変わってしまうと、
結果が変わってしまう、不安定なプログラムになります。

それを回避する為には幾つかのコツがあります。

  1. シートをWorkSheet型変数に格納する(Sheet.・・・でドットを打つと、候補が出るので楽になります)
  2. With Sheet で、頻出のシートを省略しつつ、.Range や .Cells とドットから書く

VBA

1Private Function test() 2 3 Dim ListSht As Worksheet 4 Set ListSht = ThisWorkbook.Worksheets("list") 5 6 Dim SumSht As Worksheet 7 Set SumSht = ThisWorkbook.Worksheets("年間集計") 8 9 With ListSht 10 11 Dim Row_S As Long 12 Dim Row_E As Long 13 Row_S = 3 14 Row_E = fRange_EndRow(.Cells(Row_S, 6)) 15 If (Row_S <= Row_E) = False Then Exit Function 16 17 Row_E = Row_E + 2 18 19 End With 20 21 With SumSht 22 23 Dim Row_T As Long 24 For Row_T = Row_S To Row_E 25 26 Dim Year As Integer 27 Year = ListSht.Range("F" & Row_T).Value 28 29 If Year = 0 Then 30 31 '●デバッグ用 32 Call MsgBox("年が正しくセットされていません", vbCritical + vbOKOnly) 33 34 Else 35 36 '項目行(西暦) 37 Dim Row_Sum As Long 38 Row_Sum = 7 39 40 If WorksheetFunction.CountIf(.Range(Row_Sum & ":" & Row_Sum), Year) = 0 Then 41 42 'E列 43 Dim Col_Sum As Long 44 Col_Sum = 5 45 46 Dim Row_End As Long 47 Row_End = fRange_EndRow(.Cells(Row_Sum, Col_Sum)) 48 49 Dim CopyArea As Range 50 Set CopyArea = .Range(.Cells(Row_Sum, Col_Sum), .Cells(Row_End, Col_Sum)) 51 52 With CopyArea 53 .Copy 54 .Insert xlShiftToRight, CopyOrigin:=xlFormatFromRightOrBelow 55 .PasteSpecial Paste:=xlPasteColumnWidths 56 .PasteSpecial Paste:=xlPasteFormats 57 End With 58 59 .Cells(Row_Sum, Col_Sum).Value = Year '?1つだけ空になる■ 60 61 End If 62 63 End If 64 65 Next 66 67 End With 68 69End Function 70 71Public Function fRange_EndRow(Cell As Range) As Long 72 73 With Cell.Worksheet 74 fRange_EndRow = .Cells(.Rows.Count, Cell.Column).End(xlUp).Row 75 End With 76 77End Function 78

投稿2017/10/26 09:10

ExcelVBAer

総合スコア1175

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

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

0

既に解決済みのようですが、疑問が残っているようでしたので投稿させていただきます。
(といってもハズしているかもしれませんが、参考までに。)

本題に入る前に1つ確認なのですが、年間集計シートで「年」の表示は7行目の上なので6行目のように見えますが、ソースコードでは7行目に出力しているようですね。
ここはソースコードが正しい(7行目に「年」を出力)ものとして話を進めさせていただきます。

原因?

実際に動作させたわけではないのでハズしているかもしれませんが、yearFを取得する際に対象シートを明示していないのが気になります。
対象シートを明示していないと暗黙的にアクティブシートが対象となります。
ループ処理に入る前にlistシートをアクティブにしていますが、ループ処理中にアクティブなシートが切り替わったりすると、例えば年間集計シートのF列の値をとってしまうかもしれません。

対応

これが原因であればyearF = Worksheets("list").Range("F:" & p).Valueのようにシートを明示することで改善するかもしれません。
また、これ以外にも対象シートを明示していない部分が見受けられますので、あわせて明示することをオススメします。

以下、上記内容も含めて整理したサンプルソースになります。

Dim shtList As WorkSheet Dim shtSummary As WorkSheet Set shtList = Worksheets("list") Set shtSummary = Worksheets("年間集計") Dim p As Integer Dim yearF As Integer 'listシートのF列3行目~最終データ行+2行までをループ処理 For p = 3 To WorksheetFunction.CountA(shtList.Range(shtList.Cells(3,"F"), shtList.Cells(Rows.Count, "F").End(xlUp))) + 2 'F列の値を取得(listシートの対象行・F列のセル) yearF = shtList.Cells(p, "F").Value Debug.Print "F:" & p & " , " & yearF If WorksheetFunction.CountIf(shtSummary.Range("7:7"), yearF) = 0 Then Dim rngAreaF As Range Dim rngAreaT As Range 'コピー範囲始点(年間集計.E7セル) set rngAreaF = shtSummary.Cells(7, "E") 'コピー範囲終点(年間集計.E列最終データセル) set rngAreaT = shtSummary.Cells(shtSummary.Cells(Rows.Count, "E").End(xlUp).Row, "E") 'コピー範囲の取得(始点~終点) Dim rngCopy As Range Set rngCopy = shtSummary.Range(rngAreaF, rngAreaT) With rngCopy .Copy .Insert xlShiftToRight, copyorigin:=xlFormatFromRightOrBelow .PasteSpecial Paste:=xlPasteColumnWidths .PasteSpecial Paste:=xlPasteFormats End With shtSummary.Cells(7, "E").Value = yearF '?1つだけ空になる■ End If Next p

参考になれば幸いです。

投稿2017/10/26 08:42

jawa

総合スコア3013

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

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

0

自己解決

自己解決しました。事後報告です。
.PasteSpecial Paste:=xlPasteFormats
をコメントアウトしたところ2019表示できました。

原因・理由は不明です。

ありがとうございました。

投稿2017/10/26 05:46

vitabrevisarsl1

総合スコア57

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

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

0

yearF=0となると書いてますが、ループのIf文を除いた処理だけを見た場合、正常に動作しており、yearFは2019になりました。
If文内でもyearFの更新はありませんから、yearFが0になっているのではなく、結果としてシート上0が入るということを言っているのではないかと推測します。
前述通り、ループ処理およびIf文は正しく動いていると思われますので、問題はWithから始まるコピー処理かと思われます。
決定的な原因はわからないのですが、

Cells(Rows.Count, 5).End(xlUp).Row

ここらへんが原因でしょうか。
ここのCellsは最初に選択したlistシートが対象になってしまいますので、想定外の範囲を指定している可能性があります。
こうしたら状況が変わるかもしれません。

Worksheets("年間集計").Cells(Rows.Count, 5).End(xlUp).Row

投稿2017/10/26 02:18

ttyp03

総合スコア16996

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

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

vitabrevisarsl1

2017/10/26 05:09 編集

コメントありがとうございます。 Worksheets("年間集計").Cells(Rows.Count, 5).End(xlUp).Row やってみましたが変わらずです。 デバッグで見ると、 F:3 , 2017 F:4 , 2018 F:5 , 0 です。なぜ最後が、2019のはずなのに、0なのか謎です。
ttyp03

2017/10/26 03:02

予想が外れましたね。申し訳ない。 上記の、F:3 , 0とは、yearFの値でしょうか? まずはループ内のIF文をコメントアウト等するして、yearFが正しく設定されているかどうかの確認からしてみてください。
vitabrevisarsl1

2017/10/26 05:43 編集

いえいえとんでもない。 F:5 , 0(訂正)とは、yearFの値です。 行や列の挿入削除が他のマクロの動作でなされた後ではセル参照がずれることが有るという記事もありましたが、参照シートである「list」においては行や列の挿入も削除もしていません。 デバッグで、マウスオーバーで値の確認ができます。 p=5ならyearF=2019のはずですが、なぜp=5だけyearFが0となるのか頭を抱えています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問