エクセルマクロで年号を抽出する方法について

このQ&Aのポイント
  • エクセルのマクロを使用して特定のセルから日付の年号を抽出する方法について説明します。
  • 質問文章では、特定のシートの特定のセルに入力された日付から年号を抽出する方法を学習マクロで実施しようとしています。
  • しかし、マクロの記録時にセルの表現方法に誤りがあり、コンパイルエラーが発生しています。正しいセルの表現方法を教えてください。
回答を見る
  • ベストアンサー

年号をcells形式で抽出

office2010 sheet1のD10に2017/05/22という書式の日付が入っています sheet2のAG59に上記日付の年号部分を取り出します これを学習マクロで実施すると Worksheets("sheet2").Range("AG59") = "=DBCS(YEAR(Sheet1!R[-49]C[-29]))" と記録されます R[-49]C[-29]の部分はD10セルです。 D10をcellsで表現すると、Worksheets("Sheet1").Cells(10, 4) なので、 記録マクロへ代入したら Worksheets("sheet2").Range("AG59") = "=DBCS(YEAR(Worksheets("Sheet1").Cells(10, 4)))" で表現されると思うのですが、 コンパイルエラー: 修正候補:ステートメントの最後 というエラーが発生します。 何がおかしいのでしょうか? エラーにならない書式を教えて頂きたく

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

  • ベストアンサー
回答No.1

> 年号をcells形式で > 学習マクロ 初めて聞く言葉が多いのですが・・ 「マクロの記録」で良いですか? で、「(西暦)年」を得たい、ですね? さらに(R1C1形式は慣れないので)Cellsプロパティを使いたい、 そういうことですね? > Worksheets("sheet2").Range("AG59") = > "=DBCS(YEAR(Worksheets("Sheet1").Cells(10, 4)))" > で表現されると思うのですが、 惜しいんですが、ちょっとだけ違うようです。   Worksheets("sheet2").Range("AG59") = "=Dbcs(YEAR(" & _         Worksheets("Sheet2").Cells(10, 4).Address & "))" 辺りにしてみると動くんじゃないかな、と思いますよ。 例えば、新規ブックのA1セルに適当な日付を入力し、 Sub SAMPLE()   Cells(1, 2) = "Worksheets(""Sheet1"").Cells(1, 1)"   Cells(2, 2) = Worksheets("Sheet1").Cells(1, 1)   Cells(3, 2) = Worksheets("Sheet1").Cells(1, 1).Address   ' 下3行はあえて「=」を抜いてます。   ' 必要ならマクロ実行後、セルの編集(手作業)で「=」を追加してみてください。   Cells(1, 3) = "YEAR(Worksheets(""Sheet1"").Cells(1, 1))"   Cells(2, 3) = "YEAR(" & Worksheets("Sheet1").Cells(1, 1) & ")"   Cells(3, 3) = "YEAR(" & Worksheets("Sheet1").Cells(1, 1).Address & ")"   ' で、結局   ' Cells(1, 4) = "=YEAR(Worksheets("Sheet1").Cells(1, 1))"  ' これはコンパイルエラー   Cells(2, 4) = "=YEAR(" & Worksheets("Sheet1").Cells(1, 1) & ")"   Cells(3, 4) = "=YEAR(" & Worksheets("Sheet1").Cells(1, 1).Address & ")" End Sub この違い、使ってご理解くださいませ。  ※各セルに入力された値(文字列)の違いにご注目くださいね。

3620313
質問者

お礼

回答ありがとうございます。 具体例をやってみて、動作を確認することが出来ました。 ※ 学習マクロの記載、失礼しました。 R1C1形式は慣れないというのもありますが、変数を使用するので cellsプロパティでの表現にした次第です。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

>2017/05/22という書式の日付が入っています セルの値は、日付シリアル値で入っています。これを十分知らないね。 Googleで「エクセル 日付シリアル値」で照会し、適当な記事を読んで勉強すること。VBAをやる域になっても、このことを知らない人がいるようだ。 年号が欲しい場合は年号を出す表示形式で日付を表示させて(プログラムはMSが責任を持つ) すべての表示形式と関数は日付シリアル値を対象にしている。 そこから年号を知る方法によるべきだ。 また表示形式の設定を適当に選ばないと年号は捉えられない。その年号の範囲を西暦で何年何月何日から何日までと、日付まで調べて、テーブル化して、索引するプログラムは組めますが、素人はこういうことをしてはいけない。関数の場合はTEXT、VBAなら Sub test01() MsgBox Format(Cells(1, 1), "gee/mm/dd") End Sub のような実行結果の文字列の最初の」1文字のH,S,T,Mなどで判別してはどうか。 例 西暦   年号方式 2017/5/22 H29/05/22 1920/2/3 T09/02/03 1901/4/5 M34/04/05 1939/7/7 S14/07/07 自分のコーディングをただすより、エクセルとしての普通の方法の見聞を広めよ。 エクセルVBAなのだから、他の言語プログラムなどを影響受けてはまずいばあいがあるのだ。

3620313
質問者

お礼

回答ありがとうございます。 日付シリアル値で入っています、は知ってたのですがね。

回答No.2

失礼、1です。 > > Cells(2, 4) = "=YEAR(" & Worksheets("Sheet1").Cells(1, 1) & ")" なぜ、コレがダメなのかの解説だけ補足しておきますね。 ご存知の通り、一般的に「Cells(1, 1)」と書くと、 VBEはなんとなく「.Value」を省略したんだろうな、と考えてしまいます。 つまり、内部的に「Cells(1, 1).Value」と補記し、 該当セルの「値」を拾ってきて、そのまま返します。 つまり、冒頭の式で言うと「2017/05/22」と言う値が返ってきます。 一方、ワークシート関数「YEAR」は一般的には 「シリアル値から『年』を取り出す」関数です。  ※シリアル値 = 日付を数値で表したもの   なお、2017/5/22 は 42877 です。 今日の日付から「年」を取得したいのであれば この「42877」あるいは「42877 に置き換えできる日付文字列」 またはそれらが入っている「セル番地」を引数として与えなければいけません。 さて、これらを組み合わせてみます。 Cellsプロパティは「2017/05/22」を返して、YEAR関数に与えます。 つまり「=YEAR(2017/05/22)」を処理しようとします。 で、ちょっと待った、「2017/05/22 = 18.33636・・・(割り算)」だよね。 じゃぁ「=YEAR(18.33636・・・) ⇒ YEAR("1900/1/18")」じゃん! ってことは「1900」を返せば良いね!! ・・・というエクセルとの擦れ違いが生じてしまうのです。 それを回避するため、YEAR関数には正しく「該当セル番地」を与えましょ。  × Cells(2, 4) = "=YEAR(" & Worksheets("Sheet1").Cells(1, 1) & ")"  〇 Cells(2, 4) = "=YEAR(" & Worksheets("Sheet1").Cells(1, 1).Address & ")" と、Addressプロパティを使いましょうね。 あるいは、文字列としてYEARに与えるために頑張って加工  Cells(2, 4) = "=YEAR(""" & Worksheets("Sheet1").Cells(1, 1) & """)" などでも良いですね。 ・・・というお話でした。 忘れがちですが、結構大事なんです。

3620313
質問者

お礼

回答ありがとうございます。 とても参考になりました。 日付なので、シリアル値が何かしら影響しているのでは? と思っていたので、何故おかしくなるかの例が分かりやすかったです。

関連するQ&A

  • マクロ 別シートへコピー

    いつも回答して頂きありがとうございます。 Worksheets("一覧").Paste Range("C3")と記述したら、エラーもかからずうまく貼り付け出来るが、 Worksheets("一覧").Paste Range(Cells(d,3))と記述したらエラーが発生してしまします。どうしたら上手くいくでしょうか? 下記に作成中のマクロを記載しておきます。 御指導の方よろしくお願いいたします。 Sub シートを繰り返し選択する(2)() Dim d As Integer Dim cVx As Integer d = 3 cVx = Range("IV7").End(xlToLeft).Column Worksheets(Worksheets("一覧").Cells(d, 2).Value).Range("C7:X7").Copy Worksheets("一覧").Paste Range(Cells(d, 3)) End Sub

  • excelのマクロでrangeの選択がうまくいきません。

    excelのマクロでrangeの選択がうまくいきません。 以下のマクロをsheet2に書きました。testcopyは動きますが、testcopy2は動きません。なぜなのでしょうか。どうすればいいのでしょうか。それ以外のマクロの部分との関係から、cellsを使い、数字を使ってrangeの処理をしたいのです。よろしくお願いします。 Sub testcopy() Worksheets("sheet1").Range("B3:C10").Copy Worksheets("sheet2").Range("e5").Select ActiveSheet.Paste End Sub Sub testcopy2() Worksheets("sheet1").Range(Cells(3, 2), Cells(10, 3)).Copy Worksheets("sheet2").Range("e5").Select ActiveSheet.Paste End Sub

  • エクセルのマクロでCells(j,i)を使用してデータ範囲を指定してグラフを作成する方法

    エクセルのマクロでグラフを描く時に、2つの離れた列(1列目とi列目)のデータを Cells を使用して範囲指定をしたいのですが、エラーがでてしまします。どこが間違っているか教えていただけないでしょうか? よろしくお願いいたします。 下記の式では正常にグラフは作成されます。 ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("A1:A19,C1:C19"), PlotBy _ ' :=xlColumns 下記表現でエラーが発生します。 Dim c1, c2, c3 As Range Set c1 = Worksheets("Sheet1").Range(Cells(1, 1), Cells(jmax, 1)) Set c2 = Worksheets("Sheet1").Range(Cells(1, i), Cells(jmax, i)) Set c3 = Union(c1, c2) ActiveChart.SetSourceData Source:=Sheets("Sheet1").c3, PlotBy _ :=xlColumns エラー内容 実行時エラー'438' オブジェクトは、このプロパティまたはメソッドをサポートしていません。

  • エクセルマクロエラー「'Cells'メソッドは失敗しました。'_Global'オブジェクト」について

    Excel 2000のマクロで教えてください。 あるセルに関数をいれるマクロを設定しております。  変数% = 8  Range(Cells(126, 20), Cells(155, 19 + 2 *  変数%)).FormulaR1C1 =  "=(RC[-18]-R[-1]C[-18])/0.04*100" このマクロを走らせると、たまに、 「'Cells'メソッドは失敗しました。'_Global'オブジェクト」 という、エラーがでます。 どういう意味なのでしょうか。 うまくいくときもあるので、よくわかりません。 すみませんが、教えてください。

  • マクロを作成したのですが、以下のエラーが出てきてしまいました。

    マクロを作成したのですが、以下のエラーが出てきてしまいました。  エラー:sub または function のプロシージャーの未定義 申し訳ありませんが、ご教授願います。 よろしくお願いいたします。 <マクロの内容> Sub SortTest()      Worksheets("Sheet1").Activate      Worksheets("Sheet1").Range(Cells(1, 1), Cells(100, 2)).Sort      Key1:=Worksheets("Sheet1").Cells(1, 2),order1:=xlAscending End Sub

  • Excellマクロ Cellsの範囲選択について

    エクセル2003についてお尋ねします。 A1には行番号にあたる変数が表示されるようになっています。 その変数によって選択するセルの範囲が変わるようにすることが目的でした。 「A1の行番号の5~10列目を選択する」というマクロを 下記のような記述を行いましたが、※のところでエラーが出てしまい、問題がわからずにおります。 お手数ですが解決策をご教授ください。 Sub マクロ1() Dim j As Integer j = Range("A1") Worksheets("Sheet1").Activate Range(Cells(j, 5), Cells(j, 10)).Select ←※ End Sub よろしくお願いいたします。

  • vbaの速度向上(sumif関数)

    エクセルvbaの速度を向上できないか、お知恵を貸していただきたく存じます。 以下のvba(sumif関数)をもっと速めたいです。何とかできないでしょうか。長い記載となり申し訳ないのですが、何卒よろしくお願い申し上げます。 myCnt7 = 2 Do Worksheets("●").Cells(myCnt7, 4).Value = WorksheetFunction.SumIf(Worksheets("◆").Range("B:R"), Worksheets("●").Cells(myCnt7, 3), Worksheets("◆").Range("R:R")) - WorksheetFunction.SumIf(Worksheets("★").Range("B:C"), Worksheets("●").Cells(myCnt7, 3), Worksheets("★").Range("C:C")) Worksheets("●").Cells(myCnt7, 7).Value = WorksheetFunction.SumIf(Worksheets("◆").Range("B:R"), Worksheets("●").Cells(myCnt7, 6), Worksheets("◆").Range("R:R")) - WorksheetFunction.SumIf(Worksheets("★").Range("B:C"), Worksheets("●").Cells(myCnt7, 6), Worksheets("★").Range("C:C")) Worksheets("●").Cells(myCnt7, 10).Value = WorksheetFunction.SumIf(Worksheets("◆").Range("B:R"), Worksheets("●").Cells(myCnt7, 9), Worksheets("◆").Range("R:R")) - WorksheetFunction.SumIf(Worksheets("★").Range("B:C"), Worksheets("●").Cells(myCnt7, 9), Worksheets("★").Range("C:C")) Loop While myCnt7 > 201 ※シート●のC列から3列ごとに、Sumifの検索条件があります。 ※シート●のD列から4列ごとに、Sumifの計算結果を出力させます。 ※計算対象シートは、シート◆とシート★の2つです。  シート◆のSumif合計から、シート★のSumif合計を差し引いています。  Sumifの条件自体は、どちらのシートも同じ(シート●)。 ※上記のSumif関数の記述は、3つですが、実際の記述は24あります。 ※すなわち、検索条件の組み合わせが24あり、201行分をmyCnt7でLoopさせて実行しています。

  • エクセルVBAの構文の質問です。

    エクセルVBAの構文の質問です。 グラフを作るのに列が固定ではないので記録マクロでは一部変更しなくては成らなくてその変更が上手く行きません、構文を記します。 Range("E11:E42").Select Charts.Add ActiveChart.ChartType = xlLineMarkers ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("E11:E42") ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1" 上記が記録マクロの構文ですそのRange文をCells文に変えたのが以下です。 Range("Cells(r2, c3), Cells(r3, c3)).Select Charts.Add ActiveChart.ChartType = xlLineMarkers ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range(Cells(r2, c3), Cells(r3, c3)) ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1" Range文が2ヶ所有ると思いますが最初の文はOKで2回目のRange文で以下の以下のエラーが出ます。 「'Cells'メソッドは失敗しました。'Global'オブジェクト」 「r2 c2 r3 c3」はそれぞれ変数で上の方でr2=3とかc2=9と言う風にセル位置を与えています どちら様か当方の悩みを解決してください、宜しくお願い致します。

  • VB:アクティブなシート以外でのオートフィル

    VB歴4日の初心者です。 初歩的な質問ですがご教授願います。 VBで、あるシートでオートフィルした後、別のシートでオートフィルを行いたく、 以下のようなマクロを組みました。   ~前略~ '入力行(最下段)の定義 LastRow = Range("A65535").End(xlUp).Row LastRow2 = Worksheets(3).Range("A65535").End(xlUp).Row ~中略~ '日付を追加、あとオートフィル Worksheets(1).Cells(LastRow + 1, 1) = Now Worksheets(1).Range(Cells(LastRow, 3), Cells(LastRow + 1, 3)).FillDown Worksheets(3).Cells(LastRow2 + 1, 1) = Now Worksheets(3).Range(Cells(LastRow2, 3), Cells(LastRow2 + 1, 3)).FillDown      ~後略~ 結果として、1番目のワークシートではオートフィルされたのですが、 3番目のワークシートでは行われませんでした。 日付は両方のワークシートで正常に追加されました。 ステップインで色々と観察してみたのですが、 3番目のワークシートがアクティブな時はうまくオートフィルされています。 何故でしょうか?FillDownってそういうものなのでしょうか? できればワークシートを切り替えず動作させたいのですが、、、 でも、うまく動くうごかないならしょうがないか、と思い 以下のように修正してみました。 '日付を追加、あとオートフィル Worksheets(1).Cells(LastRow + 1, 1) = Now Worksheets(1).Range(Cells(LastRow, 3), Cells(LastRow + 1, 3)).FillDown ThisWorkbook.Worksheets(3).Active Worksheets(3).Cells(LastRow2 + 1, 1) = Now Worksheets(3).Range(Cells(LastRow2, 3), Cells(LastRow2 + 1, 3)).FillDown が、うまく動きません。というかシートが切り替わりません。 何故でしょうか? 併せてお答えいただければ幸いです。 よろしくお願いします。

  • エクセルVBAでSUMPRODUCT関数の代用

    いつもお世話になっております。 現在、ある表の集計結果を返す際にマクロで 以下のような記述をしております。 Tate = Application.WorksheetFunction.CountA(Worksheets("アイテムリスト").Range("A:A")) Worksheets("アイテムリスト").Range("D2").Value = "=SUMPRODUCT((日付CSV貼付用!$AG$2:$AG$60000=D$1)*(日付CSV貼付用!$P$2:$P$60000=$A2),(日付CSV貼付用!$S$2:$S$60000))" Range("D2").Select Selection.Copy Range(Cells(2, 4), Cells(Tate, 4)).Select ActiveSheet.Paste Application.CutCopyMode = False ==== D2にSUMPRODUCT関数を入力して、必要な分だけ下にコピーしてます。 もう少しスマートというかVBA的な記述で 作業(計算)時間の短縮を図りたいと考えています。 お知恵をお貸しいただきたく、お願い申し上げます。

専門家に質問してみよう