プロが教える店舗&オフィスのセキュリティ対策術

お世話になります。

単純に、今日現在の年齢を表示させたいだけなのですが、関数ではなく、VBAで表示させたいと思っています。(現在、関数で表示させていますが、名簿対象者を追加した際に、年齢欄に関数をドラックコピーする手間を省くのが目的です)

列Nに生年月日が入力されています。
列Kに年齢を表示させたいのです。
列Nに生年月日が入っていないときは、列Kは空欄にしたいのです。(その行には会員が登録されていないので)

よろしくお願いします。

A 回答 (6件)

こんにちは。



K列の入力されているところまで処理をします。ただし1行目は項目名が入っているとして2行目から処理をします。

Dim Rng As Range
Dim Rw As Long
Rw = Range("N" & Rows.Count).End(xlUp).Row
For Each Rng In Range("N2:N" & Rw)
If Rng.Value <> "" Then Rng.Offset(, -3).Value = DateDiff("yyyy", Rng.Value, Date)
Next
    • good
    • 0
この回答へのお礼

ありがとうございます。
教えていただいたコードをThisWorkbookへ次のように貼り付けましたところ、思い通りに動きました。
Private Sub Workbook_Open()なら、ブックを開いた時ごとに再計算してくれると思ったためです。
本当は別の方法もしくはシートモジュールで別のコードを使用するのが本当なのかもしれませんが、初心者なもので、見よう見まねでやってみました。

Private Sub Workbook_Open()
Sheets("名簿").Activate
Dim Rng As Range
Dim Rw As Long
Rw = Range("N" & Rows.Count).End(xlUp).Row
For Each Rng In Range("N2:N" & Rw)
If Rng.Value <> "" Then Rng.Offset(, -3).Value = DateDiff ("yyyy", Rng.Value, Date)
Next

今回、この方法を知ったことで、大変助かりました。

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

お礼日時:2007/10/15 17:38

こんにちは。


#4 の回答者です。

>このシートチェンジでも、シートを操作できるようになるまでに、現在使用しているパソコンで約6秒の時間が必要になるようになりました。
>関数で対応していたときは1秒かからない程度でしたので、これは困ったという感じです。

それは、別の目的の質問ですね。肝心な問題を表示していただかないと、回答内容がぼけてしまいます。Excelの起動が遅いので、関数をやめて、マクロにする、という発想は、間違いないけれども、それは、システムとして作り上げることだから、かなりの技術力が必要です。単に、ひとつふたつの関数をマクロに置き換えたところで役に立つわけではありません。

今、この質問の内容を延長していっても、あまり良い解決に結びつくか分からないです。
根本的にワークシートの再計算を遅くしているものは何かというものがはっきりしないと、マクロでの解決も、あまり意味のないものになってしまいます。はっきり言って、イベント・ドリブン型のマクロは役に立ちません。場合によっては使わないほうがよいです。いちいち、再計算を呼び起こすことになるだけです。

Excelのステータスバー(ソフトの下の縁)に、起動時に何か出ているはずです。「再計算」とか、アドイン名とか、何に一番時間がかかっているか、そういう点から解決の糸口を探さないとダメです。

今、この場でいえるのは、

OS 2000, XP
C:\Documents and Settings\<ユーザー名>\Local Settings\Temp\

OS 98, Me

C:\Windows\Temp

の中で、Excelを終了して、そこにあるファイルを削除してみることですね。ただし、すべて削除できるとは限りませんが、それはかまいません。

後は、細かい情報をいただかないと、マクロで解決するというような安易な方法でよいのか分かりません。
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。

このブックには教えていただいた別のマクロも記述しているので、私の理解が追いついていない状況です。

今回は、多くの方にご協力いただいたので、それを理解できるよう、勉強するつまりです。

それまでは、Wendy02様に教えていただいた関数を使用したいと思います。
このIf関数で指定列が空欄であった場合は空欄として表示するというのは、私も多く使用しているのですが、今回は関数で解決するという点に目が向きませんでした。頭の柔軟性がないなぁと反省しました。

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

お礼日時:2007/10/19 12:24

#03です。

ブックを開いた際に自動実行する方法として
 Private Sub Workbook_Open()
でも、何ら問題はありません。

以下はN列に「日付」が入力されたときK列にDATEDIF関数を埋め込むマクロです。シート名タブ右クリック→コードの表示で開く画面に貼り付けます。
これはワークシート関数を利用するので「再計算」の必要がない方法になります。既に解決策を見つけられておりますので、あくまで「ご参考まで」です。

Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng, r As Range
  Set rng = Intersect(Target, Columns("N:N"))
  If Not rng Is Nothing Then
    For Each r In rng
      If IsDate(r.Value) Then
        r.Offset(0, -3).Formula = "=DATEDIF(" & r.Address(0, 0) & ",TODAY(),""Y"")"
      Else
        r.Offset(0, -3).ClearContents
      End If
    Next r
  End If
End Sub
    • good
    • 0
この回答へのお礼

これはすごいですね。生年月日を打つとすぐに年齢が表示されます。
Private Sub Workbook_Open() ですと、一度ブックを閉じて再度開かないと年齢計算しないので困っていました。

ただ、みなさんにいろいろ教えていただいたのに大変申し訳ないのですが、年齢計算のVBAを入れたら、ブックのオープンでも、このシートチェンジでも、シートを操作できるようになるまでに、現在使用しているパソコンで約6秒の時間が必要になるようになりました。

関数で対応していたときは1秒かからない程度でしたので、これは困ったという感じです。

VBAの方法を教えていただいて、大変ありがとうございました。感謝しております。

お礼日時:2007/10/16 17:25

こんにちは。



>(現在、関数で表示させていますが、名簿対象者を追加した際に、年齢欄に関数をドラックコピーする手間を省くのが目的です)

基本的なことですから、最低限、その程度の手間はしてください。ドラッグが嫌なら、コピーして、範囲を選択して貼り付けでもよいですし、#2のzap35さんの■のクリックでもよいです。(ただし、左隣に入力されていること)

K2 ~
=IF(N2="","",DATEDIF(N2,TODAY(),"y"))

この式は、N列に入れていなければ、何も出てきません。


なお、VBAのDateDiff 関数は、計算方法が違うので、そのままでは使えません。
    • good
    • 0
この回答へのお礼

 N列に入れていなければ、何も出てこない関数式を教えていただき、ありがとうございました。これなら、最初から名簿対象者プラス10000行下まで設定しておけば問題ないですね。


 そもそも、質問文を短く書こうとあせってしまい、必要な情報を書かなくて申し訳ありませんでした。そのことで、Wendy02様に不快な思いをさせてしまったらと思うと、質問文のまずさに後悔しています。
 私個人はドラッグ操作を面倒とは思っていませんし、ワークシートのDATEDIF関数が入力されたセルの右下隅にある小さな■をダブルクリックしてのオートフィルもエクセル操作としてはよく使っています。

 問題は、私の同僚(管理職から新人バイトさんまで)のほとんどがエクセルが苦手だということです。
 この名簿はほとんど私が入力しているのですが、私が休みや席を外している時に受付対応としてすぐに入力しなければならない事態がごくまれに発生します。
 エクセルが苦手という同僚のレベルは、ドラッグという意味がわからない(使ったことがない)という程度です。エクセルを使ったことがない人もいます。

 多分、説明してもエクセル操作を数ヶ月しなければ忘れてしまうでしょうし、新人バイトさんや人事異動で同僚が替わればまた説明しなければなりません。
 それより何より、私も3月には人事異動になるかもしれません。
 この名簿登録方法はマニュアルを画面をハードコピーして操作方法の解説書を作っていますが、皆さん読まずに「わからないので、年齢は手で計算して直接打ち込みました」と言って来ます。(これでは、次の誕生日を過ぎても年齢が変わらず、名簿が狂ってしまうのに・・・)

 そこで、初心者でも極力入力の手間(この場合は、名簿対象者を追加した際に、年齢欄に関数をドラックコピーする手間)を省いて、間違いのない名簿を作成しようと思った次第です。

 すみません。長々と愚痴まじりに説明させていただきました。
 Wendy02様には、いつも的確な回答をいただいたり、他の質問者様へなさる回答を参考にさせていただいているので、質問に至った経緯を説明させていただきたいと思いました。


 今回も的確なご教示、大変ありがとうございました。
 

お礼日時:2007/10/15 18:19

>今日現在の年齢を表示させたいだけなのですが


年齢は誕生日を過ぎたら変わりますね。ですから入力シートに日付を入れたら年齢を計算させるだけでなく、そのブックを開いた時に、過去に入力されている日付から年齢を全件再計算する必要もありますよ。

そのためには入力シートのモジュールシートに
Private Sub Worksheet_Change(ByVal Target As Range)
'  年齢計算処理
End Sub

ワークブックのモジュールシートに
Private Sub Workbook_Open()
'  年齢の再計算処理
End Sub

を書かなくてはなりません。また実務で使うなら入力された値が日付でない場合の判定も加える方が良いと思います。それにはIsDate関数が使えます。具体的なマクロは書きませんが、ご参考まで。

>ドラックコピーする手間を省くのが目的
ワークシートのDATEDIF関数が入力されたセルの右下隅にある小さな■をダブルクリックすればオートフィルが使えますから、ドラッグするよりは簡単にできるかもしれません。
    • good
    • 0
この回答へのお礼

年齢の再計算のことを教えていただきありがとうございます。

私も、年齢の再計算のことは考えていたので、自分なりに(初心者の無謀さがでているでしょうが)この質問でNo.1様に教えていただいたコードをThisWorkbookへ次のように貼り付けましたところ、思い通りに動きました。
Private Sub Workbook_Open()なら、ブックを開いた時ごとに再計算してくれると思ったためです。

本当はzap35様の方法を取らなくてはならないのですね。
未熟者ですので、方法が分かりません。
ですが、とりあえず、日付は正確に打つということを前提にしていますが、なんとか動いています。
ありがとうございます。


Private Sub Workbook_Open()
Sheets("名簿").Activate
Dim Rng As Range
Dim Rw As Long
Rw = Range("N" & Rows.Count).End(xlUp).Row
For Each Rng In Range("N2:N" & Rw)
If Rng.Value <> "" Then Rng.Offset(, -3).Value = DateDiff ("yyyy", Rng.Value, Date)
Next

また、
>ワークシートのDATEDIF関数が入力されたセルの右下隅にある小さな■をダブルクリックすればオートフィルが使えますから、ドラッグするよりは簡単にできるかもしれません。

の情報ありがとうございました。
こういう、便利な情報を付け足していただく親切さにありがたさを感じました。

お礼日時:2007/10/15 17:56

#1です。

K列ではなくてN列の入力があるところまでです。
    • good
    • 0
この回答へのお礼

入力があるところまでというのも大変勉強になりました。

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

お礼日時:2007/10/15 17:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!