• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Excel VBAについて)

Excel VBAについての質問

このQ&Aのポイント
  • Excel VBAを使用して、年齢データに基づいて年代を設定するマクロを作成したが正常に動作しない
  • Excel 2003で作成したが、将来的には2007でも使用したい
  • データ数が多いため、ワークシート関数ではなくマクロで処理したい

質問者が選んだベストアンサー

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは。 ちょっと説明文と、ご提示のコードに不整合があるようですが、 説明を優先させます。 > 年齢がN列にあるとき、M列に年代を入れたいと思います。( M列=13列め N列=14列め 最下行の取得は、A列を基準。 N列の値=年齢を、一の位で切り捨てた値を、 M列に Sub ByAge()   Dim i As Long, N As Integer   Range("M1").Value = "年代別"   For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row     Cells(i, 13).Value = (Cells(i, 14).Value \ 10) * 10   Next i   MsgBox "完了!" End Sub

leeiria
質問者

お礼

すっきりとしたわかりやすいコードですね。こんなに短くできるなんて…感動しました! ありがとうございました。

leeiria
質問者

補足

すみません、文章が間違いでコードが正しいです。 でもN列とM列を入れ替えたら正常に動作しました。

その他の回答 (6)

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.7

#1、cjです。気になったので追加レスしてみます。 > 以下のように作成しましたが、すべてに20と入ったり正常に動作しないときがあります。 > もっと正確に実行できるコードを教えてください。 #1では、簡単さを意識して書いていたので、 あらためて、保守を意識したものを書いてみました。   セルの値のデータ型が何であれ、表示されている文字を取得して、   2桁の数字であれば、一の位を "0" に置換して年代を出力します。   このやり方は、セルへの入力や数式の建て方などにイレギュラーがあっても、   表示された年齢に対して処理しますから、誤った出力結果を避けることができます。   万が一、2桁の数値でない値(エラー値含む)だった場合は、   出力しないように書きましたから、   実行後に、空白セルを探せば容易に検証できるようになっています。   10歳未満、100歳以上の場合も空白セルになってしまいますが、特別に手当てしてあげてください。 もっと厳しくすることも考えましたが、難しくない程度に堅牢に、という狙いで、 メンテのし易さも考慮しています。 ' ' ================================================================= Sub Re8291599c()   Dim r As Range   Dim sTmp As String On Error GoTo Exit_   With Application     .ScreenUpdating = False     .EnableEvents = False     .Calculation = xlCalculationManual     .Interactive = False     .IgnoreRemoteRequests = True   End With   Columns("N").NumberFormatLocal = "G/標準"   Range("N1").Value = "年代別"   For Each r In Range("M2:M" & Cells(Rows.Count, 1).End(xlUp).Row)     sTmp = Trim$(r.Text)     If sTmp Like "##" Then       Mid(sTmp, 2) = "0"       r(1, 2).Value = sTmp     End If   Next Exit_:   If Err Then MsgBox Err & vbLf & Err.Description, vbExclamation   With Application     .IgnoreRemoteRequests = False     .Calculation = xlCalculationAutomatic     .EnableEvents = True     .Interactive = True     .ScreenUpdating = True   End With End Sub ' ' ================================================================= #スレが盛り上がっちゃって、検証するのも大変でしょうけれど、 焦らず頑張ってください。

leeiria
質問者

お礼

早速検証したところ、おっしゃる通りの結果になりました。こんなコードが自分でも書けたら、、、と思います。 度々ご尽力いただき本当にありがとうございました。

leeiria
質問者

補足

このデータはこの処理後にピボットテーブルにすることを検討しているので、文字があっても、10歳未満、100歳以上の場合でも空白セルになってくれるのは助かります。

  • keithin
  • ベストアンサー率66% (5278/7941)
回答No.6

ありゃ、NとMを入れ替えたらマクロを直し忘れました。 sub macro1r1()  with range("N2:N" & cells(rows.count, "M").end(xlup).row)   .formula = "=IF(M2="""","""",IF(M2>=20,ROUNDDOWN(M2,-1),""""))"   .value = .value  end with  msgbox "DONE" end sub しつれいしました。

leeiria
質問者

お礼

度々ありがとうございます!

  • kmetu
  • ベストアンサー率41% (562/1346)
回答No.5

No3です 一応M列には数値しか入っていないという前提でやってますが、万が一数値以外が入力される可能性があるのでしたらIsNumericを利用して Sub ByAgeSample() Dim MyRange As Range Range("N1").Value = "年代別" For Each MyRange In Range("M2:M" & Range("A" & Rows.Count).End(xlUp).Row) 'If IsNumeric(MyRange.Value) Then ← こちらより↓のほうがいいそうです。 If WorksheetFunction.IsNumber(MyRange.Value) Then Select Case Int(MyRange.Value / 10) Case 6 Range("N" & MyRange.Row).Value = 60 Case 5 Range("N" & MyRange.Row).Value = 50 Case 4 Range("N" & MyRange.Row).Value = 40 Case 3 Range("N" & MyRange.Row).Value = 30 Case 2 Range("N" & MyRange.Row).Value = 20 End Select Else MsgBox MyRange.Row & "行に数値以外が入力されています" Range("M" & MyRange.Row).Select Exit Sub End If Next End Sub などのようにしてください。

leeiria
質問者

お礼

絶対数値しか入らないといいたいのですが、私以外の人が何名かで使用するのでそうはいいきれず...回避があったほうがいいと思いました。 勉強になります。ありがとうございました。

回答No.4

>年齢がN列にあるとき、M列に年代を入れたいと思います。 文章と、コードには矛盾があります。 最初はコードを優先させていただきます。 '// Sub Ages_Class()  Dim c As Range  Dim i As Long  Range("N1").Value = "年代別"  i = Cells(Rows.Count, 1).End(xlUp).Row  For Each c In Range("M2", Cells(i, 13))   If VarType(c.Value) = vbDouble Then    c.Offset(, 1).Value = Int(c.Value / 10) * 10    End If  Next c  MsgBox "完了!" End Sub '// もし、文章どおり >年齢がN列にあるとき、M列に年代 とするなら、 '// Sub Ages_Class()  Dim c As Range  Dim i As Long  Range("M1").Value = "年代別"  i = Cells(Rows.Count, 1).End(xlUp).Row  For Each c In Range("N2", Cells(i, 14))   If VarType(c.Value) = vbDouble Then    c.Offset(, -1).Value = Int(c.Value / 10) * 10    End If  Next c  MsgBox "完了!" End Sub '//

leeiria
質問者

お礼

もし年齢列に文字が入っていても、エラーで中断することなく最終行まで処理してくれました。また100歳や5歳など入れた場合もちゃんと処理してくれました。 素晴らしいコードですね!ありがとうございました。

leeiria
質問者

補足

すみません、コードが正しいです。両方書いていただき恐縮です。

  • kmetu
  • ベストアンサー率41% (562/1346)
回答No.3

40代のところのIF文が間違ってることを除いては普通に動きそうですけど、正常に動作しないとは不思議ですね。うちでテストしても正常に動きました。何か他の要因があって正常に動かないのではないでしょうか。 とりあえずcase文を使ったサンプルを Sub ByAgeSample() Dim MyRange As Range Range("N1").Value = "年代別" For Each MyRange In Range("M2:M" & Range("A" & Rows.Count).End(xlUp).Row) Select Case Int(MyRange.Value / 10) Case 6 Range("N" & MyRange.Row).Value = 60 Case 5 Range("N" & MyRange.Row).Value = 50 Case 4 Range("N" & MyRange.Row).Value = 40 Case 3 Range("N" & MyRange.Row).Value = 30 Case 2 Range("N" & MyRange.Row).Value = 20 End Select Next MsgBox "完了!" End Sub

leeiria
質問者

お礼

私もこの場合IfよりSelect Caseのほうが確実と思い、何度が書いたのですがすべて失敗で動きませんでした。 このように記述するのですね。勉強になりました。 ありがとうございました。

  • keithin
  • ベストアンサー率66% (5278/7941)
回答No.2

>年齢がN列にあるとき、M列に年代を入れたい マクロでは逆になってますので,マクロの方が正しいとします。 sub macro1()  with range("N2:N" & cells(rows.count, "N").end(xlup).row)   .formula = "=IF(M2="""","""",IF(M2>=20,ROUNDDOWN(M2,-1),""""))"   .value = .value  end with  msgbox "DONE" end sub

leeiria
質問者

補足

わかり難い質問にもかかわらず理解していただきありがとうございます。おっしゃる通り、マクロが正しいです。

関連するQ&A