ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Excel(エクセル)活用コミュのVLOOKUP関数を使って差し込み印刷をしたい

  • mixiチェック
  • このエントリーをはてなブックマークに追加
EXCEL2003で作った勤務管理票があります。

そのシートの中の
【社員名】というセルに社員の名前、
【社員番号】というセルに社員番号が次々と表示されて印刷出来るように
したいと思います。
そこで
VLOOKUP関数を使いマクロで印刷できるようにしました。


ところが
画面番号に【3】と入力してEnterを押しても、
前に入力した【2】の番号のまま
画面が切り替わりません。
上書きしたらやっと 【3】の画面に変わります。
どうしてこうなるのか原因がわかりません。

参照する表に空白があると上手く動いてくれないのでしょうか?
今はまだ新入社員の番号が分らないため、空白にしてあるせいでしょうか?

よろしくご教示くださいませ。



コメント(64)

万年カレンダーの作成方法は、
「EXCEL カレンダー」
で検索すると、たくさん出て来ます。

これなんかは、そのまま参考になるんじゃないかな?
すごく基本的なことから説明しているようです。
http://www11.plala.or.jp/koma_Excel/contents1/mame1001/mame100101.html
案内 Sheet14...これらがアクティブだとエラー処理してないのでエラーですねあせあせ
>まゆさん

ちなみに、
Range("社員名簿") = Range("印刷開始")
って、
Range("画面番号") = Range("印刷開始")
の間違いなんでは?
>>27
間違いですね。気がつきませんでした(^^;

24:訂正
Range("画面番号") = Range("印刷開始" & strSheetMonth)
画面番号の後ろの番号はA2の値と同じなんだからもっと簡単に出来ましたね。


Sub Macro1()
 Dim strSheetMonth As String

  strSheetMonth = Sheets(ActiveSheet.Name).Range("A2").Value
  Range("画面番号" & strSheetMonth) = Range("印刷開始" & strSheetMonth)

  Do While Range("画面番号" & strSheetMonth)<= Range("印刷終了" & strSheetMonth)
   Sheets(ActiveSheet.Name).PrintOut
   Range("画面番号" & strSheetMonth) = Range("画面番号" & strSheetMonth) + 1
  Loop
End Sub


Sheets(ActiveSheet.Name).Range("A2").Value のところは、
ActiveSheet.Range("A2").Value でもかまいません。
Golden様、たつや.com様

早々にお返事いただきありがとうございました。
金曜日の夜から試行錯誤しながらやっと今思い通りのものが完成しました。

結果としては
たつや.com様の教えてくださった万年カレンダーのサイトを参考にさせていただき
まず、【1枚仕立ての勤務管理表】を完成させて、万年使えるモノを作成しました。
これは、年・月が変わっても祝日は自動的に赤色に表示してくれるし、
うるう年もちゃんと表示してくれて修正不要で感激です!!

マクロに関しては、
Golden様の29コメントのマクロをそっくりそのまま使わせていただきました。
これで期待した通りの印刷が可能になりました。
大満足です♪
本当にありがとうございました。
これから、勤務管理表だけでなくいろんなシーンに使えそうです。

ひとつ疑問なのですが、
Golden様の コメント29のマクロの3行目の
  strSheetMonth = Sheets(ActiveSheet.Name).Range("A2").Value
 
の部分の("A2")は コメント21のように
A2のセルに 月数
が入っていなければならないのですよね?

私の作った勤務管理表のA2のセルには空っぽなんですが
どういうわけか印刷は指示通りしてくれました。

気にしなくてもこのまま使って大丈夫でしょうか?
>>まゆさん

シート構成を変更されたのですね。
では前のマクロで問題ないと思われます。(下記、少々直しました)
29のコードは構成を変更されない場合のコードです。
今となっては必要ないです。
Sheets(ActiveSheet.Name).PrintOutはアクティブになったシートを印刷します。

新しいファイルはセルや範囲の名前が同じですよね?

Sub Macro1() 
  Range("画面番号") = Range("印刷開始")
  Do While Range("画面番号")<= Range("印刷終了")
   Sheets(ActiveSheet.Name).PrintOut
   Range("画面番号") = Range("画面番号") + 1
  Loop
End Sub
ご存知かもしれませんが、言葉が足りないので補足いたします。

>>アクティブになったシートを印刷します。

アクティブシートとは、現在使用できる状態のシート(画面上に表示されているシート)のことをいいます。
Golden様

ありがとうございます。
コメント32のマクロにさっそく直しました(^^;

29のマクロはせっかく教えて頂いたものなので、
当初の12か月で作成したシートで試しながら、
また今からマクロの勉強をさせていただきます。
ほんとに助かりました。
ありがとうございました。
良かったですね。

そこまで完成したら、今度は、マクロを実行すれば、
指定した年月(ならば「はい」)と翌月(ならば「いいえ」)
のどちらを印刷するのか聞いて来るようなダイアログが
出て来ると面白いかも知れないですねw

かなり怠けられそうw
>>私以外の人が触ったとき、 その月だけ・・・
トピ主以外の人も使うのであれば、印刷ボタン押したときに表示されてるカレンダーが過去に印刷されているか判別して警告するとか…。印刷しなおす場合もあるだろうから注意だけにとどめた方がいいかも。

であれば、過去の場合は、マクロを強制中止してしまっても良いかも?
警告しても、「はい」と押してしまう人は絶対いるので。
万が一、過去の印刷をするとしても、数人だと思うので、手動で十分かと…
さらに、未来過ぎる(3ヶ月以上?1年以上?)のも、強制中止で良いかも?

それと、ボタンは簡単に押してしまう場合があるので、少なくとも、
「印刷を開始しますか?」というダイアログくらいは必要かも知れません。
さらに、「○年○月の印刷を開始しますか?」だとなお良いかも?

もちろん、私の勝手な想像ですので、使い方により、検討ください。
こんな感じかしら…。

Option Explicit

Sub Macro1()
  Dim intAnswer As Integer
  
  intAnswer = MsgBox(Format(Range("A1").Value, "yyyy年mm月") & _
          "の印刷を開始しますか?", vbCrLf & vbYesNo + vbQuestion, "印刷確認")
  If intAnswer = vbYes Then
    Range("画面番号") = Range("印刷開始")
    Do While Range("画面番号") <= Range("印刷終了")
     Sheets(ActiveSheet.Name).PrintOut
     Range("画面番号") = Range("画面番号") + 1
    Loop
  Else
    Exit Sub
  End If
End Sub
自分が作ったマクロBookを他人が使う場合、いろんな配慮が必要になりますよね。時には思いもつかないようなエラーを発生させちゃったり(^^;
使っていく過程で、必要なエラー処理などを付け加えていく感じでどうでしょう?
数日前も、自分が作ったマクロファイルがおかしい日付を吐いたので怒られたのですが、調べてみたらその人のパソコンの日付が合ってなくて…画面右下をWクリックして修正しました(^^;

>>未来過ぎる(3ヶ月以上?1年以上?)のも、強制中止で良いかも?
A1セルの条件付き書式で未来過ぎる場合は赤く塗りつぶすとか、データ規則で制限するなどでも対応できますよね。

トピ主さん、38のコードではカレンダーの基準値がA1にあるという想定で書きました。(サンプルファイルがA1だったので)違ってたら修正してください。
>>過去の場合は、マクロを強制中止してしまっても良いかも
忘れてました(^^;
印刷終了後にセルIV1へA1の日付を書き込んでおき、印刷ボタン押すと、セルIV1とA1を比較させ、A1の日付がIV1の日付より古い場合と同じ場合(印刷1回以上)は止めました。

Option Explicit

Sub Macro1()
  Dim intAnswer As Integer
  
  If Range("IV1").Value >= Range("A1").Value Or _
    Range("IV1").Value = Range("A1").Value Then Exit Sub
  
  intAnswer = MsgBox(Format(Range("A1").Value, "yyyy年mm月") & _
          "の印刷を開始しますか?", vbCrLf & vbYesNo + vbQuestion, "印刷確認")
  If intAnswer = vbYes Then
    Range("画面番号") = Range("印刷開始")
    Do While Range("画面番号") <= Range("印刷終了")
     Sheets(ActiveSheet.Name).PrintOut
     Range("画面番号") = Range("画面番号") + 1
    Loop
    Range("IV1").Value = Range("A1").Value
  Else
    Exit Sub
  End If
End Sub
まぁ、強制終了する場合、黙って終了ではなく、理由メッセージ
は出しましょう。なぜ印刷しないのか原因が分からなくなります。

それと、過去と未来は、TODAY関数で比較すれば簡単だと…
参考
J1=DATE(YEAR(TODAY()),MONTH(TODAY())-1,DAY(TODAY()))
K1=DATE(YEAR(TODAY()),MONTH(TODAY())+3,DAY(TODAY()))
出勤時間が迫ってるのでメッセージボックスの中身はトピ主さんに替えてもらって、とりあえず印刷できるユーザーを限定するようにしてみました。
下記は3人までです。付け加える場合は数字を増やしてください。

>>過去と未来は、TODAY関数で比較すれば簡単だと…
この課題は帰宅後ということで…(^^;

Option Explicit
Option Base 1

Sub Macro1()
  Dim objWSN As Object
  Dim strUserName(3) As String
  Dim i As Integer
  Dim BooFlag As Boolean
  Dim intAnswer As Integer
  
  Set objWSN = CreateObject("WScript.Network")
  strUserName(1) = "Golden"
  strUserName(2) = "hoge"
  strUserName(3) = "higehoge"

  For i = 1 To 3
    If objWSN.UserName = strUserName(i) Then BooFlag = True
  Next i
  If BooFlag = False Then
    MsgBox "ユーザー名:" & objWSN.UserName & " は印刷できません"
    Exit Sub
  End If
 
  If Range("IV1").Value >= Range("A1").Value Or _
    Range("IV1").Value = Range("A1").Value Then
    MsgBox "印刷無効"
    Exit Sub
  End If



 Set objWSN = Nothing
End Sub
すっ、すっ、すごい!!げっそり
痒いところに手が届くというか、ほんと至れり尽くせりで、ここのコミュニティーにはホント感謝感激ですっ!!
実は昨日あれから
『ほんとに印刷しますか?』みたいなのものを付け加えたくていろいろ調べていたのですが どこの部分に付け加えたら良いのかさっぱり分からなくて…
とりあえず今の状態になったことだけでも自分では十分過ぎるほど満足なので、今日は会社までの足どりが軽いです(笑)
早速また今夜試してみますね!
本当にありがとうございます。
「EXCEL メッセージ」で検索すると
http://www11.plala.or.jp/koma_Excel/contents4/mame4034/mame403404.html
が出て来ます。

>それと、過去と未来は、TODAY関数で比較すれば簡単だと…
>参考
>J1=DATE(YEAR(TODAY()),MONTH(TODAY())-1,DAY(TODAY()))
>K1=DATE(YEAR(TODAY()),MONTH(TODAY())+3,DAY(TODAY()))

こんな簡単じゃなかったです。
今月(4月)から再来月(6月)までの印刷を許可するということは、
4月1日〜6月1日までの印刷でなければなりません。
「EXCEL 1ヶ月後」で検索すると、
http://plaza.rakuten.co.jp/pasodairy/diary/200502090000/
に、EDATE関数があるので…

携帯からなので、ここまで(^_^;)
EDATEと同様のマクロ関数はDateAddです…と思います。
ちょっとやってみます。
↓こんな感じ。
DateAdd("m", 1, Cells(1, 1).Value)
行き詰ってしまいました。

Str = "DATE(YEAR(TODAY()),MONTH(TODAY()),1)"
myDate = Evaluate(Str)
として、DateAdd("m", -1, myDate) で、(現在の月-11日)を
もとめようとしても、下記のコードをイミディエイトに入れるとおかしな日付が返ってきます。

?DateAdd("m", -1, myDate)
1899/11/30

なぜかな。StrとmyDateのデータ型はString? Date?…。
2か月先をもとめると下記のようになりました。

?DateAdd("m", 2, myDate)
1900/02/28
先月を印刷する必要はないので、1ヶ月前を求める必要はないです。
また、無理に全てマクロで計算・判定する必要もないと思います。

印刷の指定月は、日を指定しないので、見かけ上、○月1日となります。
今日(4/15)、今月の印刷をする場合は、見かけ上、4月1日。
来月は、5月1日。先月を間違えて指定すると、見かけ上、3月1日。

今月(4月)から再来月(6月)までの印刷を許可する場合、
見かけ上、4月1日〜6月1日までの印刷でなければなりません。

先月であれば、3月1日が、4月1日〜6月1日に入っているかどうかを
判定すれば良いと思います。

また、EDATE関数は、アドインなので、なるべく使わず、簡易的に、
J1=DATE(YEAR(TODAY()),MONTH(TODAY()),1)
K1=TODAY()+190  ←7月の印刷も許可する可能性があるが良しとする。
としても良いと思います。

できましたあせあせ(飛び散る汗)

Option Explicit
Option Base 1

Sub Macro1()
  Dim objWSN As Object
  Dim strUserName(3) As String
  Dim i As Integer
  Dim BooFlag As Boolean
  Dim intAnswer As Integer
'  ----------------------------------------------------------------------
  Set objWSN = CreateObject("WScript.Network")
    strUserName(1) = "Golden"
    strUserName(2) = "Hoge"
    strUserName(3) = "HogeHoge"
  For i = 1 To UBound(strUserName)
    If objWSN.UserName = strUserName(i) Then BooFlag = True
  Next i
  If BooFlag = False Then
    MsgBox "ユーザー名:" & objWSN.UserName & "は無効です"
    Exit Sub
  End If
  Set objWSN = Nothing
'  ----------------------------------------------------------------------
  If Range("A1").Value < DateAdd("d", -30, Date) Or _
    DateAdd("m", 2, Date) < Range("A1").Value Then
    MsgBox "印刷無効です"
    Exit Sub
  End If
'  ----------------------------------------------------------------------
  intAnswer = MsgBox(Format(Range("A1").Value, "yyyy年mm月") & _
          "の印刷を開始しますか?", vbCrLf & vbYesNo + vbQuestion, "印刷確認")
  If intAnswer = vbYes Then
    Range("画面番号") = Range("印刷開始")
    Do While Range("画面番号") <= Range("印刷終了")
     Sheets(ActiveSheet.Name).PrintOut
     Range("画面番号") = Range("画面番号") + 1
    Loop
  Else
    Exit Sub
  End If
End Sub
>>For i = 1 To 3
を、
>>For i = 1 To UBound(strUserName)
に修正しました。

配列の数を取得してForの最大値にしました。
これで配列の数を書き換える場所がひとつ減りますね。
49を修正しました。
このままでは手動で印刷できてしまうので、ユーザー制限のコードは
Private Sub Workbook_Open()
End Sub
の間に書いて、ファイルを開いたときに実行し、対象外のユーザーのときはシートは非表示のままにした方がいいですね。
まあ、今回はこのままにしておきます。

で、印刷可能期間ですが、
>>←7月の印刷も許可する可能性があるが良しとする。
とありますが、妥協したくないので改良修正しました(^_^;)
CDate()って便利ですね。文字列を日付として扱ってくれます。
条件は満たしてると思いますがご確認ください。

Sub Macro1()
  Dim objWSN As Object
  Dim strUserName(3) As String
  Dim i As Integer
  Dim BooFlag As Boolean
  Dim strDate As String
  Dim strPast As String
  Dim strFuture As String
  Dim intAnswer As Integer
'  ----------------------------------------------------------------------
  Set objWSN = CreateObject("WScript.Network")
  strUserName(1) = "Golden"
  strUserName(2) = "Hoge"
  strUserName(3) = "HogeHoge"
    For i = 1 To UBound(strUserName)
      If objWSN.UserName = strUserName(i) Then BooFlag = True
    Next i
    If BooFlag = False Then
      MsgBox "ユーザー: " & objWSN.UserName & " は印刷できません", _
            vbCritical, "ユーザー名 確認"
      Exit Sub
    End If
  Set objWSN = Nothing
'  ----------------------------------------------------------------------
  strDate = Range("A1").Value
  strPast = Date - Day(Date)
  strFuture = Year(Date) & "/" & Month(Date) + 2 & "/1"
    If CDate(strDate) < CDate(strPast) Or _
      CDate(strFuture) < CDate(strDate) Then
      MsgBox "印刷無効です  ", vbExclamation, "印刷月数 確認"
      Exit Sub
    End If
'  ----------------------------------------------------------------------
  intAnswer = MsgBox(Format(strDate, "yyyy年mm月") & _
          "の印刷を開始しますか?", vbYesNo + vbQuestion, "印刷確認")
  If intAnswer = vbYes Then
    Range("画面番号") = Range("印刷開始")
    Do While Range("画面番号") <= Range("印刷終了")
     Sheets(ActiveSheet.Name).PrintOut
     Range("画面番号") = Range("画面番号") + 1
    Loop
  Else
    Exit Sub
  End If
End Sub
Golden様

すっごくハイレベルなマクロを完成してくださって
本当にありがとうございました。

今更こんな質問をさせていただくのは
すごく恥ずかしいんですが、
このマクロを実行すると

私のPCでは
『○○は 印刷できません』
というメッセージが出てきます。
なので、次に進めません(*ノ_<*)

ユーザー名のところを○○に変えたらいいのかと思って変えてみたんですが
どうやらこれとは違うようでどこをどのように変えていいのかわかりません。

呆れられて見捨てられてしまいそうですが、
どうかよろしくご教示お願いいたします。

まゆさん、こんばんは。

これを標準モジュールにコピペして実行してください。
A2にユーザー名を書き込みます。
A2にデータがある場合は違うセルに設定してください。

Sub ログインユーザー名を取得()
Dim objWSN As Object
Set objWSN = CreateObject("WScript.Network")
Range("A2").Value = objWSN.UserName
Set objWSN = Nothing
End Sub

で、A2に入力されたユーザー名をコード内の下記の部分にコピペしてください。
これで出来るはずですが・・・。

  strUserName(1) = "○○"
  strUserName(2) = "Golden"
  strUserName(3) = "HogeHoge"
補足です。
↓はMacro1()の上に必ずつけて(宣言して)ください。
Option Explicit
Option Base 1

特に↓は配列・インデックス番号を0からではなく、1から始める宣言です。
Option Base 1

本来は下記のようになります。
strUserName(0) = "○○"
strUserName(1) = "Golden"
strUserName(2) = "HogeHoge"

で、
Dim strUserName(2) As String
の部分は 0 1 2 で3つなので(2)となります。
Golden様

お疲れのところをご親切にありがとうございます。

お恥ずかしいことに
55コメントを読ませていただき、今やっと気が付きました。

strUserName(1) = "Golden"
  strUserName(2) = "Hoge"
  strUserName(3) = "HogeHoge"

↑ここを変えなきゃいけなかったのですね??
私はてっきり

 MsgBox "ユーザー: " & objWSN.UserName & " は印刷できません", _
            vbCritical, "ユーザー名 確認"

を変えるのかと勘違いしていました。

(余談ですがhogeっていったい誰?何?って思ったので
早速ググってみましたところ、
「必要な文字に置き換えて使ってください」
という意味だったのですね!?
これも一緒に勉強になりました。)

そこで
早速この部分の名前を変えてみましたら、
ちゃんと印刷出来ました。
本当にありがとうございました。
こんなにすごいマクロを私が仕事で使えるなんてホント夢みたいです。
(私はなんにも苦労してないのに・・・・)
ホントにありがとうございました。
動いてよかったです(^o^;
ファイルを複数の人が使う場合はその人たちのユーザー名を書き込めばいいわけです。まあ、今回の勤務管理表の印刷にはいらない機能かもしれませんが、印刷や閲覧を限定したい場合はブックを開くときに実行するようにしておき、マクロをパスワードロックします。
ユーザーを追加する場合はDim・・・の変数宣言の()内の数も忘れずに変更してください。

■ブックのイベント
http://www.k1simplify.com/vba/tipsleaf/leaf312.html

ところで、印刷有効期間の指定はうまくできてるでしょうか?
この部分のコードを説明しますと、
strDateはA1のカレンダーの日付です。

strPastは現在の日付から現在の日にち(可変します)15を引きその日付を格納します。今なら2008/3/31となるはずです。= Date - Day(Date)

strFutureは現在の日付から年数、月数を抜き出し2ヶ月加算、日にちは一日に指定した日付文字列を格納します。今なら2008/6/1です。= Year(Date) & "/" & Month(Date) + 2 & "/1"
で、A1が7月の場合や3月の場合は印刷できないようにしてます。
1年後、新人に印刷を頼んで、困りそう。
1年後には、マクロの内容忘れそう…
その時は、マクロ無効にして1枚づつ印刷するしかないでしょうね。
'ユーザー制限のコードをコメント化しちゃえば解決しますけど。
'-------------解りやすいように区切ってますし・・・。
'内容は忘れないうちにコメントつけてください。

う〜ん、印刷程度に、ユーザ制限かける意味が…
ユーザ名に拘るなら、印刷終了後、
「○○さん、お疲れ様でした!」
というメッセージが出るくらいが調度良い。
必要・不必要な機能はトピ主さんが付け加えたり削除してもらえばいいと私は思います。

本人も印刷制限かけられたマクロ…
削除する場所も分からないかもよ?
やりすぎ
たつや.com様 Golden様

いろんなケースを想定して それに対応できる方法を
たくさん考えてくださって本当にありがとうございます。

忘れないうちに別シートにマニュアルにして保存しておきます。
マクロの印刷ボタンを押したあと、やっぱり止めたいと思ったとき
キャンセルできるようになっていたことが
大変嬉しかったです。
私はとてもうっかりしているので、事前にプリンターを選択し忘れたまま
マクロボタンを押してしまい、間違えて請求伝票用紙に
印刷してしまったりってことがよくあるのです;(+_+);
プリンターが起動し始めてやっとプリンター機の選択間違いに気がつくんです。
このマクロだとそれからでも充分間に合うので
これでミスプリの被害も減りそうです。

>印刷終了後、
「○○さん、お疲れ様でした!」

このメッセージが出てきたら、なんだかほのぼのして和みますね。
マクロってホントいろんなことが出来るのですね。
上司が見たら喜ぶかもしれません(*^θ^*)

とても解りやすい説明に感謝しています。
本当にご親切にありがとうございました。

ログインすると、残り25件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

Excel(エクセル)活用 更新情報

Excel(エクセル)活用のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。