[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『印刷範囲の設定』(hr)
A列に年、B列に月、C列に日が入力されています。
印刷がうまくいかなくなりました。
年が2020年から2021年になったことが原因かと思うのですが、どのように修正したらよいでしょうか。
よろしくお願いいたします。
Dim r As Range, rr As Range, c As Range
If 最終行 >= 35 And 最終日 >= 4 Then Set r = Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious).Offset(, -28) Set rr = Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious).Offset(, -28) For Each c In Range("B:B").SpecialCells(xlCellTypeVisible) If c.Value = r.Value Then Set rr = Union(rr, c) Next c With ActiveSheet .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1 .PageSetup.PrintArea = "" .PageSetup.PrintArea = Application.Range(rr(1), rr(rr.Count)).EntireRow.Resize(30, 30).Address .PrintOut End With End If
< 使用 Excel:Excel2019、使用 OS:Windows10 >
■2
>年が2020年から2021年になったことが原因かと思うのですが
どうしてそう思ったのでしょうか?
マクロが正しく動いているかどうかチェックするには、結果から想像するより、1行ずつ実行して確認していくアプローチのほうが有用に思えます。
「ステップ実行」という言葉を聞いたことがなければ↓を読んでみてください。
【ステップ実行】 https://www.239-programing.com/excel-vba/basic/basic023.html http://plus1excel.web.fc2.com/learning/l301/t405.html
ついでに↓も覚えてしまいましょう。
【イミディエイトウィンドウ】 https://www.239-programing.com/excel-vba/basic/basic024.html https://excel-ubara.com/excelvba1/EXCELVBA486.html
【ローカルウィンドウ】 https://excel-ubara.com/excelvba4/EXCEL266.html http://excelvba.pc-users.net/fol8/8_2.html
■3
1、2それぞれに関連しますが、そのマクロはどこに記述されているのでしょうか?
仮に「標準モジュール」に記述しているなら、全部ActiveSheetでの話になるから、With ActiveSheet はもっと前に書いたほうが分かりやすいかもですね。
ちなみに、ActiveSheetでの話なら
> B列に月
>Columns(30)〜〜〜Offset(, -28)
> For Each c In Range("B:B").SpecialCells(xlCellTypeVisible)
> If c.Value = r.Value Then Set rr = Union(rr, c)
> Next c
だから、年じゃなくて、「B列」の「月」に着目したほうがいいんじゃないですか?
(もこな2) 2021/01/06(水) 22:54
Set rr = Union(rr, c)
(もこな2) 2021/01/06(水) 22:59
〜.EntireRow.Resize(30, 30)
↑のようにしているので、おそらくやりたいことは
(1) AD列でデータが入っている最終セルを調べる (2) (1)の行のB列に入っている値である【月】を取得する (3) B列の表示セルのうち、取得した【月】が最初に出てくるセルを調べる (4) (3)で調べたセルの行のA列から「Resize(30, 30)」した範囲を印刷範囲として設定する
ということではないでしょうか?
想像が合ってれば、↓のようなアプローチでも可能だと思うのでやはり「年」は関係してないのでは?
Sub さんぷる() Dim 発見セル As Range Dim 検索値 As Variant '←適切なものに変えてください Dim c As Range
Stop ' ブレークポイントの代わり
With ActiveSheet '▼(1) AD列の最終セルを調べる(1) Set 発見セル = .Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious)
If 発見セル Is Nothing Then MsgBox "AD列にデータがありません" Else '▼(2) 調べたセル行のB列の値を取得する 検索値 = .Cells(発見セル.Row, "B").Value Else
'▼(3) B列の可視セルを巡回して、値が検索値にマッチするセルを調べる For Each c In .Range("B:B").SpecialCells(xlCellTypeVisible) If c.Value = 検索値 Then Exit For Next c
'▼印刷設定をする With .PageSetup .FitToPagesWide = 1 .FitToPagesTall = 1 .PrintArea = c.Offset(, -1).Resize(30, 30).Address '★(4) End With
.PrintPreview End With End Sub
(もこな2) 2021/01/07(木) 03:22
現在の月のデータを印刷したいです。(31日まである月なら1日〜31日)
今(1月8日)であれば、2021年1月1日〜31日を印刷します。
月頭(例えば2月2日)であれば、2月2日から1月前までを印刷したいです。
エクセルが2020年1月から始まっているのですが、なぜか2020年1月が印刷されてしまい困っています。
Sub ()
Dim 最終行 As Variant Dim 最終日 As String Dim r As Range, rr As Range, c As Range
Sheets("sheet1").Select
最終行 = Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious).Row 'Columns(30)はAD列 最終日 = Cells(最終行, 3).Value
If 最終行 <= 34 Then With ActiveSheet .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1 .PageSetup.PrintArea = "" .PageSetup.PrintArea = Range(Cells(3, 1), Cells(34, 30)).Address .PrintOut End With End If
If 最終行 >= 35 And 最終日 <= 3 Then With ActiveSheet .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1 .PageSetup.PrintArea = "" .PageSetup.PrintArea = Range(Cells(最終行 - 31, 1), Cells(最終行, 30)).Address .PrintOut End With End If
If 最終行 >= 35 And 最終日 >= 4 Then Set r = Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious).Offset(, -28) Set rr = Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious).Offset(, -28) For Each c In Range("B:B").SpecialCells(xlCellTypeVisible) If c.Value = r.Value Then Set rr = Union(rr, c) Next c With ActiveSheet .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1 .PageSetup.PrintArea = "" .PageSetup.PrintArea = Application.Range(rr(1), rr(rr.Count)).EntireRow.Resize(30, 30).Address .PrintOut End With End If
End Sub
1月8日の場合、最後のifが該当するため、それ以降で間違いが起こっているかと思いました。
お分かりになる方おしえてください。
よろしくお願いいたします。
(hr) 2021/01/08(金) 00:23
Sub テキトー() Dim 最終行 As Long '←変更 Dim 最終日 As Long '←変更 Dim c As Range
Stop 'ブレークポイントの代わり
With Sheets("sheet1") 最終行 = .Range("AD:AD").Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious).Row 最終日 = .Cells(最終行, "C").Value Debug.Print "最終行は " & 最終行 Debug.Print "最終日は " & 最終日
'共通処理1 .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1
'分岐処理 If 最終行 <= 34 Then .PageSetup.PrintArea = "A3:AD34" Else If 最終日 <= 3 Then .PageSetup.PrintArea = .Cells(最終行 - 31, 1).Resize(30, 30).Address Else For Each c In .Range("B:B").SpecialCells(xlCellTypeVisible) If c.Value = .Cells(最終行, "B").Value Then Exit For Next c Debug.Print "「" & c.Value & "」が最初に出てくるのは" & c.Address(0, 0) & "です" .PageSetup.PrintArea = c.Offset(, -1).Resize(30, 30).Address End If End If
'共通処理2 .PrintPreview End With End Sub
(もこな2) 2021/01/08(金) 09:16
(もこな2) 2021/01/08(金) 09:28
イミディエイトには、
最終行は374
最終日は6
「1」が最初に出てくるのはB3です
となっています。
2020年の「1」から印刷してしまっているんですね。
最終行を含む月としているはずですが、年越しはできないでしょうか。
(hr) 2021/01/08(金) 10:03
ちなみに、SpecialCells(xlCellTypeVisible)を使っているのに理由はあるのですか?
意味がないなら3〜最終行までを順番に見ていって、該当する【年】と【月】が最初にでてくる行を調べればよいですね。
(もこな2) 2021/01/08(金) 10:16
Sub テキトー2() Dim 最終セル As Range Dim i As Long
Stop 'ブレークポイントの代わり
With Sheets("sheet1") Set 最終セル = .Range("AD3:AD" & .Rows.Count).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious)
If 最終セル Is Nothing Then Exit Sub
'共通処理1 .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1
'分岐処理 If 最終セル.Row <= 34 Then .PageSetup.PrintArea = "A3:AD34" Else If .Cells(最終セル.Row, "B").Value <= 3 Then .PageSetup.PrintArea = .Cells(最終セル.Row, "A").Resize(30, 30).Address Else '▼「年」と「月」を調べる For i = 3 To 最終セル.Row If .Cells(i, "A").Value = .Cells(最終セル.Row, "A").Value And _ .Cells(i, "B").Value = .Cells(最終セル.Row, "B").Value Then
.PageSetup.PrintArea = .Cells(i, "A").Resize(30, 30).Address Exit For End If Next i End If End If
'共通処理2 .PrintPreview End With End Sub
尤も、年月日が別々のセルに分かれておらず、ちゃんと日付型のデータとして存在していればこんなめんどくさい処理は必要ないわけですが・・・
(もこな2) 2021/01/10(日) 16:28
■5
再三になりますが、「年」が関係ないと言っていた意味は分かっていただけましたか?
■6
>例えば1月6日が最終入力されている場合
そのときに、以下を実行すると、イミディエイトになんと出力されますか?
Sub テキトー2() Dim 最終セル As Range Dim i As Long
With Sheets("sheet1") Set 最終セル = .Range("AD3:AD" & .Rows.Count).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious) If 最終セル Is Nothing Then Exit Sub
Debug.Print "最終セルは " & .Cells(最終セル.Row, "A").Value & "年" & .Cells(最終セル.Row, "B").Value & "月" & .Cells(最終セル.Row, "C").Value & "日"
For i = 3 To 最終セル.Row If .Cells(i, "A").Value = .Cells(最終セル.Row, "A").Value And _ .Cells(i, "B").Value = .Cells(最終セル.Row, "B").Value Then Exit For End If Next i
Debug.Print "起点年月日は " & .Cells(i, "A").Value & "年" & .Cells(i, "B").Value & "月" & .Cells(i, "C").Value & "日" Debug.Print "セル範囲は" & .Cells(i, "A").Resize(30, 30).Address(0, 0)
End With End Sub
■7
>例えば1月6日が最終入力されている場合、1月1日から1月31日までが印刷範囲にならなければいけません。
ならば、↓はおかしいですよね?なんという数字が入るのが正しいと思いますか?
.Resize(30, 30) ~~
(もこな2) 2021/01/13(水) 19:01
シートレイアウトが示されてないので、アレですが、 単純に考えて、こういう感じでいいのではないでしょうか Sub sample()
Dim r As Range
Set r = Columns(30).Cells(Rows.Count, 1).End(xlUp).Offset(, -28) For i = 0 To -30 Step -1 If r.Offset(i - 1) <> r.Value Then Exit For Next For j = 0 To 30 If r.Offset(j + 1) <> r.Value Then Exit For Next
With ActiveSheet .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1 .PageSetup.PrintArea = "" .PageSetup.PrintArea = Range(r.Offset(i), r.Offset(j)).EntireRow.Resize(, 30).Address .PrintPreview End With
End Sub (´・ω・`) 2021/01/13(水) 20:17
1
完成するまでは続けます。
2
該当する【年】と【月】が最初に出てくることを調べるために、【年】の情報も必要かと思ってしまいました。
3
イミディエイトには、
最終セルは2021年1月6日
起点年月日は年月日
セル範囲はA1812:AD1841
となっています。
4
以前、rr.offset(,-1).Resize(,30).Adressとしていたのですが、うまくいかなかったので修正しました。
(hr) 2021/01/14(木) 20:18
Sub test01()
Dim 本日 As Double Dim Sh As Sheet1 Set Sh = Sheets("sheet1")
本日 = Now '本日 = DateSerial(2020, 2, 1)
Dim 当年 As Range, 当月 As Range Set 当年 = Find_Range(Year(本日), Columns("A:A"), xlValues, xlPart, MatchCase:=False, MatchByte:=True) Set 当月 = Find_Range(Month(本日), 当年.Offset(0, 1), xlValues, xlPart, MatchCase:=False, MatchByte:=True)
Debug.Print Year(本日) & "年の範囲"; 当年.Address(0, 0) Debug.Print Month(本日) & "月の範囲(印刷?)"; 当月.Offset(0, -1).Resize(, 30).Address(0, 0) End Sub
Function Find_Range(Find_Item As Variant, _
Search_Range As Range, _ Optional LookIn As XlFindLookIn = xlValues, _ Optional LookAt As XlLookAt = xlPart, _ Optional MatchCase As Boolean = False, _ Optional MatchByte As Boolean = True) As Range ' 'https://wv4short.com/excel-vba-find_range/ より ' Dim c As Range, FirstAddress As String
With Search_Range Set c = .Find( _ What:=Find_Item, _ LookIn:=LookIn, _ LookAt:=LookAt, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=MatchCase, _ MatchByte:=MatchByte, _ SearchFormat:=False) 'Delete this term for XL2000 and earlier If Not c Is Nothing Then Set Find_Range = c FirstAddress = c.Address Do Set Find_Range = Union(Find_Range, c) Set c = .FindNext(c) Loop While Not c Is Nothing And c.Address <> FirstAddress End If End With End Function (ふむ〜) 2021/01/14(木) 22:01
■9
>該当する【年】と【月】が最初に出てくることを調べるために、【年】の情報も必要かと思ってしまいました。
よくわかりません。なんでそう思ったか聞いてるんじゃなくて、「年」が関係ないと言っていた意味が【理解できたか】と聞いています。
こちらとしては、「月」であるB列しかチェックしてなかったので「年」が確認できてなかったということが理解できましたなどと返ってくるのを期待したわけですが・・・
■10
>起点年月日は年月日
なんか変ですね。
↓でもう一度実行してみてください。
Sub テキトー3() Dim 最終セル As Range Dim i As Long
With Sheets("sheet1") Set 最終セル = .Range("AD3:AD" & .Rows.Count).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious) If 最終セル Is Nothing Then Exit Sub
Debug.Print "最終セルは " & 最終セル.Address(0, 0) Debug.Print "基準日は " & .Cells(最終セル.Row, "A").Value & "年" & .Cells(最終セル.Row, "B").Value & "月" & .Cells(最終セル.Row, "C").Value & "日"
For i = 3 To 最終セル.Row If .Cells(i, "A").Value = .Cells(最終セル.Row, "A").Value And _ .Cells(i, "B").Value = .Cells(最終セル.Row, "B").Value Then Debug.Print i & "行目でヒットしました" Exit For End If Next i
Debug.Print "起点年月日は " & .Cells(i, "A").Value & "年" & .Cells(i, "B").Value & "月" & .Cells(i, "C").Value & "日" Debug.Print "セル範囲は" & .Cells(i, "A").Resize(30, 30).Address(0, 0)
End With End Sub
■11
>以前、rr.offset(,-1).Resize(,30).Adressとしていたのですが、うまくいかなかったので修正しました。
こちらもよくわかりません。
>>なんという数字が入るのが正しいと思いますか?
と問うていたので、1月【31】日までだから、「31」が入るべきです。と答えが返ってくるのを期待してました。
■12
ちなみに、日付型のデータが入っている列はないのですか?
別案として、日付型のデータがどこかにある、あるいは作業列を設けることができるなら↓みたいな感じでも可能だと思います。
Sub 日付型のデータがあれば() Dim 最終セル As Range Dim 基準日 As Date With Sheets("sheet1") Set 最終セル = .Range("AD3:AD" & .Rows.Count).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious) If 最終セル Is Nothing Then Exit Sub
'▼既に日付型のデータがあれば不要 .Range("AE2").Value = "作業列" .Range("AE3:AE" & .Cells(.Rows.Count, "C").End(xlUp).Row).Formula = "=DATE(A3,B3,C3)"
'▼日にちで何年何月を対象にするか判定 If Day(最終セル.Offset(, 1).Value) <= 3 Then 基準日 = DateAdd("m", -1, 最終セル.Offset(, 1).Value) Else 基準日 = 最終セル.Offset(, 1).Value End If
'▼オートフィルタで対象年月のみを抽出 .AutoFilterMode = False .Range("AE2:AE" & 最終セル.Row).AutoFilter Field:=1, _ Criteria1:=">=" & DateSerial(Year(基準日), Month(基準日), 1), _ Operator:=xlAnd, _ Criteria2:="<=" & DateSerial(Year(基準日), Month(基準日) + 1, 0) End With End Sub
このように対象年月の分だけオートフィルタで抽出すれば、他は非表示になるから毎回ページ設定(と印刷範囲の設定)をする必要はなくなりますよね。
(もこな2) 2021/01/14(木) 22:48
1
期待した答えができずに申し訳ありません。
2
もう一度実行した結果は、
最終セルはAD374
基準日は2021年1月6日
369行目でヒットしました
起点年月日は2021年1月1日
セルの範囲はA369:AD398
となりました。
3
月報形式シートには、関数を使用使用しているセルはあります。
A3には2020、B3には1、C3には1と入力されています。(2020年1月1日という意味です)
A4にはYEAR(DATE($A3,$B3,$C3)+1)
B4にはMONTH(DATE($A3,$B3,$C3)+1)
C4にはDAY(DATE($A3,$B3,$C3)+1)
他のセルには数値が入力されているだけです。
よろしくお願いします。
(hr) 2021/01/15(金) 16:38
■14
>もう一度実行した結果は、
こんどは、ちゃんと成功したみたいですね。
その状態なら、「テキトー2」もちゃんと動きませんか?
■15
>月報形式シートには、関数を使用使用しているセルはあります。
仰ってる意味がわかりません。日付型のデータがないか?と確認したことへのレスですか?
もしそうだとたら、ものすごく回りくどいように感じます。
私なら
A3セルに 2020/1/1 と【日付】を入力 〃 の表示形式を yyyy に設定
B3セルに =A3 と【数式】を入力 〃 の表示形式を m に設定
C3セルに =A3 と【数式】を入力 〃 の表示形式を d に設定
A3:C3を必要なだけフィルコピー
のようにします。
そうすれば、A〜C列はいずれも日付型のデータになりますから、↓のようにどこかの列さえ確認すれば、特定の年月日を探せるようになるでしょう。
Sub 名前がないマクロを整理してみた() '2021/01/08(金) 00:23に提示されたものを改造 Dim 発見セル As Range Dim buf As String Dim 開始行 As Long, 終了行 As Long Dim MyDate As Date
With Sheets("sheet1") Set 発見セル = .Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious) If 発見セル Is Nothing Then Exit Sub
If 発見セル.Row <= 34 Then buf = "A3:AD34" Else MyDate = .Cells(発見セル.Row, "A").Value If Day(MyDate) <= 3 Then 開始行 = Application.Match(CLng(DateAdd("m", -1, MyDate)), .Range("A:A"), 0) '先月の同日を探す 終了行 = 発見セル.Row Else 開始行 = Application.Match(CLng(DateSerial(Year(MyDate), Month(MyDate), 1)), .Range("A:A"), 0) '当月の1日を探す 終了行 = Application.Match(CLng(DateSerial(Year(MyDate), Month(MyDate) + 1, 0)), .Range("A:A"), 0) '翌月の0日(=当月末)を探す End If buf = "A" & 開始行 & ":AD" & 終了行 End If
'▼共通処理 .PageSetup.FitToPagesWide = 1 .PageSetup.FitToPagesTall = 1 .PageSetup.PrintArea = buf '.PrintOut End With End Sub
(もこな2) 2021/01/16(土) 16:03
私なりには理解できたと思っています。
すみません。
まだ「名前がないマクロを整理してみた」をトライできていないのですが、とりあえず「テキトー2」でちゃんと稼働しました。
ただ、当初、1日から月末までを印刷する計画でした。
しかし、今の状態では、30日分を印刷するようになっているかと思います。
すると、30日で終わらない月については、月末までを正しく印刷できないと思います。
恐縮ですが、「テキトー2」で月末までを印刷する方法も教えていただけないでしょうか。
よろしくお願いいたします。
(hr) 2021/01/18(月) 22:51
.Resize(30, 30) ~~
>まだ「名前がないマクロを整理してみた」をトライできていないのですが
ちゃんとステップ実行して研究してください。↓に思いっきり書いてますよ
DateSerial(Year(MyDate), Month(MyDate) + 1, 0)), .Range("A:A"), 0) '翌月の0日(=当月末)
あとはDay関数で日にちを取り出せばいいでしょう。
(もこな2) 2021/01/18(月) 23:24
A〜C列を2020/1/1と入力し表示形式を変更するやり方では、他のマクロの部分が影響するため触わらずに、当月末を探し、当月中を印刷する方法を知りたいです。
(hr) 2021/01/24(日) 11:19
Sub 実験() Debug.Print Day(DateSerial(2020, 1 + 1, 0)), DateSerial(2020, 1 + 1, 0) Debug.Print Day(DateSerial(2020, 2 + 1, 0)), DateSerial(2020, 2 + 1, 0) Debug.Print Day(DateSerial(2020, 3 + 1, 0)), DateSerial(2020, 3 + 1, 0) Debug.Print "" Debug.Print Day(DateSerial(2020, 11 + 1, 0)), DateSerial(2020, 11 + 1, 0) Debug.Print Day(DateSerial(2020, 12 + 1, 0)), DateSerial(2020, 12 + 1, 0) End Sub
(もこな2) 2021/01/24(日) 13:41
テキトー3で、iと比較してA列が同じで、B列が+1で、C列が1となるときが翌月の1日となるので、その一行上のAD列まで、と範囲としたらよいのかと考えましたが、どのように記載したらよいのかわかりませんでした。
その考えで行くなら、最終行から順番にC列の最終行まで巡回していき、【次の行】が1であるものを探せばいいんじゃないですか?
最終行 = Columns(30).Find("*", LookIn:=xlValues, SearchDirection:=xlPrevious).Row 'Columns(30)はAD列 For i = 最終行 To ActiveSheet.Cells(ActiveSheet.Rows.Count, "C").Row If ActiveSheet.Cells(i + 1, "C").Value = 1 Then MsgBox i & "行目で見つけました" Exit For End If Next i
(もこな2) 2021/01/24(日) 20:55
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.