【お知らせ】カテゴリの見直しについて

生年月日から学年を計算しようと以下のようにVBを用いて作りました。が、9月までは正しく学年が表示されたのですが、10月になったとたん、一つ前の学年が表示されるようになりました。

Function Jokyo(ByVal Umare As Variant) As String
Dim idx As Integer
Dim moji As String
If IsNull(Umare) Then
Jokyo = ""
Exit Function
End If

'4月~12月での学齢計算
If Month(Date) >= "4" Then
idx = DateDiff("yyyy", Umare, DateSerial(Year(Date), 4, 1))
If Format(Umare, "mmdd") < "0401" Then
idx = idx + 1
End If
ElseIf Month(Date) < "4" Then
idx = DateDiff("yyyy", Umare, DateSerial(Year(Date) - 1, 4, 1))
If Format(Umare, "mmdd") < "0401" Then
idx = idx + 1
End If
Else
idx = 19
End If
'--------------------------------------------------
Select Case idx
Case 0 To 4
moji = "未入学"
Case 5
moji = "幼稚園年少"
Case 6
moji = "幼稚園年長"
Case 7 To 12
moji = "小学" & idx - 6 & "年生"
Case 13 To 15
moji = "中学" & idx - 12 & "年生"
Case 16 To 18
moji = "高校" & idx - 15 & "年生"
Case Else
moji = "既卒生"
End Select

Jokyo = moji

End Function

A 回答 (2件)

10行目:Monthの解は数値なので比較する値は""で囲わない


If Month(Date) >= "4" Then => If Month(Date) >= 4 Then

16行目:10行目と同じ、且つ10行目の例外値のすべてなので
ElseIf Month(Date) < "4" Then => Else

21行目~22行目:無意味なので削除
Else
idx = 19

後、問題とは別ですが
Umareは日付ですよね。
If IsNull(Umare) Then => If IsDate(Umare) Then
の方がいいのでは?

もうひとつ学齢の計算なら日付の比較は4月1日ではなく4月2日だと思うけど...
idx = DateDiff("yyyy", Umare, DateSerial(Year(Date), 4, 1))
idx = DateDiff("yyyy", Umare, DateSerial(Year(Date) - 1, 4, 1))
    • good
    • 0

#1さんの回答で、ほとんど、こちらの考えている部分と一致していますので、やめようとは思いましたが、私なら、こういうコードを書く(本格的なものとは違います)というサンプルコードを置いておきます。

参考にしてみてください。

 If IsNull(Umare) Then
Jokyo = ""
Null値は、Null値をVariant型の変数に入れないと判定できません。つまり、人為的にいれないと出ません。ワークシート等なら、="" や =Empty です。ただし、IsEmpty(変数)は、ここでは違います。

また、Jokyo="" は、関数が文字型なら、値を入れなければ、「""」(長さ0の文字列)になります。

なお、今回は、あえてDateDiff は使いません。理由は特にありません。

たぶん、ワークシートで使う分には、ByVal キーワードは不要な気がします。

'//
Function EdGrade(ByVal yrBirth As Variant) As String
Dim d As Date, i As Long
Dim dif As Long
Dim stat As String
'エラー排除
 If IsDate(yrBirth) = False Then EdGrade = CVErr(xlErrValue): Exit Function
 d = yrBirth
 If d > Date Then EdGrade = CVErr(xlErrNA): Exit Function
 If DateSerial(Year(Date), Month(d), Day(d)) > DateSerial(Year(Date), 4, 1) Then
   i = 0
 Else
   i = 1
 End If
 dif = Year(Date) - Year(d) + i
  Select Case dif
    Case 0 To 4
      stat = "未入学"
    Case 5
      stat = "幼稚園年少"
    Case 6
      stat = "幼稚園年長"
    Case 7 To 12
      stat = "小学" & dif - 6 & "年生"
    Case 13 To 15
      stat = "中学" & dif - 12 & "年生"
    Case 16 To 18
      stat = "高校" & dif - 15 & "年生"
    Case Else
      stat = "既卒生"
  End Select
  EdGrade = stat
End Function
    • good
    • 0

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qエクセル2000。 名簿の生年月日欄入力から、学年欄を自動的に入力したい

お願いいたします。

年齢雑多な大人・子供混ざった名簿があり、生年月日の欄(列D)はすでにあります。
新規に学年の欄(列E)を設けたいのですが、生年月日を利用して自動的に記入させるにはどうすればよいでしょうか。高校以上の大人は空欄にします。

私は、エクセルは入力と並べ替え、フィルタ、簡単な関数(合計・平均程度)が使える程度です。

Aベストアンサー

◆下のURLが参考になると思います

参考URL:http://www2.odn.ne.jp/excel/waza/function.html#SEC25

QExcel起動時に特定のワークシートを開かせたい。

エクセルの起動時に特定のワークシートを開くように設定したいのですが方法がわかりません。
申し訳ありませんが、アドバイスお願いいたします。
また、VBAで教えていただけると助かります。
よろしくお願いいたします。

Aベストアンサー

以下のマクロでシート名を変更して下さい

Private Sub Workbook_Open()
Worksheets("シート名").Activate
End Sub

マクロはALT+F11でVBE画面を開き、「VBAProjectエクスプローラのThisWorkBook右クリック→「コードの表示」で表示される画面にペーストします。ブック保存後に再度ブックを開いてみてください

QAccessで生年月日から現在の年齢を求めるには?

Access2002を使用しています。
生年月日のフィールドに「1965/05/01」を入力しているとします。
その場合、現在の年齢フィールドに今日現在の年齢の「41歳」と出すようにするにはどういった式をどこに入れればよいでしょうか?

また、現在の年齢と何ヶ月かまで求めることは出来ますか?
例えば上記の例ですと、「41歳3ヶ月」と。
勿論、何ヶ月というフィールドは別に作ってもOKです。

どうぞよろしくお願い致します。

Aベストアンサー

>すようにするにはどういった式をどこに入れればよいでしょうか?
下の式を出したいところに書きます
年齢: DateDiff("yyyy",[誕生日],Date())+(Format([誕生日],"mmdd")>Format(Date(),"mmdd")) & "才"

>年齢と何ヶ月かまで求めることは出来ますか?
(DateDiff("m",[誕生日],Date())+(Format([誕生日],"dd")>Format(Date(),"dd")))\12 & "才" & (DateDiff("m",[誕生日],Date())+(Format([誕生日],"dd")>Format(Date(),"dd"))) Mod 12 & "ヶ月"

QACCESSでフォームを使って、テーブルを参照、データ入力、データ更新をしたいのです

フォームを使って、テーブルを参照、データ入力、データ更新をしたいのです。

売上テーブル

 ID   商品コード  日付    金額 
 1    G1     20080101  532153
 2    G1     20080101  564281
 3    G1     20080301  538123
 4    J4     20080301  124531
 5    J4     20080302  125483

ID:オートナンバー 商品コード:数値型 日付:数値型 金額:数値型

これを使い、
フォームではまず

レコードナンバーを入力画面
       ↓
レコード番号を入れると、そのレコードのデーターが画面に表示され、
その画面で修正可能
       ↓
 保存 ボタンで保存

という流れです。

レコードナンバーはIDを使おうと思っています。

データの量が莫大な為、コンポボックスなどは使えません。

できるだけ、VBAなどは使わずに作りたいです。

よろしくお願い致します。

フォームを使って、テーブルを参照、データ入力、データ更新をしたいのです。

売上テーブル

 ID   商品コード  日付    金額 
 1    G1     20080101  532153
 2    G1     20080101  564281
 3    G1     20080301  538123
 4    J4     20080301  124531
 5    J4     20080302  125483

ID:オートナンバー 商品コード:数値型 日付:数値型 金額:数値型

これを使い、
フォームではまず

レコードナンバーを入...続きを読む

Aベストアンサー

まずそのテーブルを基にしてフォームを作成します。
そのフォームのヘッダー部分にテキストボックスを配置後、一旦
上書き保存。
フォームのレコードソースを
SELECT *
FROM テーブル名 WHERE ID=[Forms]![フォーム名]![テキストボックス名]
とします。
次にテキストボックスの更新後処理に
Me.Requery
とすれば完成です。
フォームを開いてテキストボックスにID入力後エンターしてください。

保存に関しては、コマンドボタン作成後クリック時イベントに
DoCmd.RunCommand acCmdSaveRecord
とすれば良いでしょう。

この手のモノは検索すれば相当数ヒットするので、そちらを参考にされるのもよろしいかと。

QACCESS IIF関数 複数条件の設定について

 選択クエリにおいて、あるフィールド「 X」 のレコード数値が
 
  0<[X]<=50   であれば A 
  50<[X]<=100  であれば B 
  100<[X]<=150  であれば C

 と表記させるフィールド「Y」を追加したいと考えています。
 この場合、Yのフィールド設定で指定する数式についてご教授願います。

 一応、
  IIf(0<[X]<=50,"A","") Or IIf(50<[X]<=100,"B","") Or IIf(100<[X]<=150,"C","")

  としましたが、実行すると、Yの列がすべて「-1」と表記されてしまいます。

 何卒よろしくお願いいたします。

Aベストアンサー

a)IIF関数で対応する場合:
 IIF関数の第2引数または第3引数に、IIF関数を入れ子とする必要があります。

式: IIF([X]<=0, "", IIF([X]<=50, "A", IIF([X]<=100, "B", IIF([X]<=150, "C", ""))))


b)別の組込関数を使用する場合:
 IIF関数は二択ですので入れ子にする必要がありますが、Accessのクエリで
 使用できる、似た機能の関数に、Switch関数というものもあります。
 これであれば、入れ子にする必要がなくなります。
 (詳しくは、Accessのヘルプを参照下さい)

式: Switch([X]<=0, "", [X]<=50, "A", [X]<=100, "B", [X]<=150, "C", True, "")


なお、数学あるいは一般生活では確かに「0<[X]<=50」という表記をしますが、
Accessの関数などではこれだと正しい結果が得られません。
正しく認識させるためには、等号・不等号を挟んだ式は、「左辺」と「右辺」の
2つの要素からなる形にする必要があります。
(「0<[X]<=50」は「[X]>0 And [X]>=50」と分割してやる、と)

但し、今回のご質問のような『連続した範囲』であれば、前(左)で既出となる
式の要素で「[X]<=0」が「真(=-1)」とならなかった時点で、「[X]>0」が保証
されますので、上記のように、「[X]>0」を省略して「[X]<=50」だけを条件として
指定すればOk、ということになります。
(「0<[X]<=50」の次が「80<[X]<120」などのように、「50~80」が欠けた
 場合は、省略ができない、と)


【参考】
「0<[X]<=50」は、このままだと「0 < ([X]<=50)」という式と解釈されます。
この場合、「[X]<=50」は、「真(=-1)」か「偽(=0)」か「Null」のいずれかに
なります。
何にせよ、「0<[X]<=50」全体として「正(=-1)」となることがないため、
ご質問の式では、IIF関数は常に第3引数に指定された値「""」を返す
ことになります。

この結果、式全体としては「"" Or "" Or ""」という形となり、「0かNull」
以外なので、「真(=-1)」という値が返された、ということです。

なお、Nullについては、以前、他の方の質問につけた回答も、併せて参考までに:
http://oshiete.goo.ne.jp/qa/4850675.html

a)IIF関数で対応する場合:
 IIF関数の第2引数または第3引数に、IIF関数を入れ子とする必要があります。

式: IIF([X]<=0, "", IIF([X]<=50, "A", IIF([X]<=100, "B", IIF([X]<=150, "C", ""))))


b)別の組込関数を使用する場合:
 IIF関数は二択ですので入れ子にする必要がありますが、Accessのクエリで
 使用できる、似た機能の関数に、Switch関数というものもあります。
 これであれば、入れ子にする必要がなくなります。
 (詳しくは、Accessのヘルプを参照下さい)

式: Switch([X]<=0, "", [X]<=50, "A"...続きを読む


人気Q&Aランキング