電子書籍の厳選無料作品が豊富!

エクセルのデータに
5月24日(金)
5月24日(木)
など、
西暦を除いた日付情報が文字列として入っています。

VBAでループし、yyyy/mm/ddに治そうと思ってるのですが、
今年の分は日付型に変換すれば、勝手に2013年になりますが、
今年以外の日付も2013年になってしまいます。

手掛かりになるのは曜日なのですが、曜日から西暦を割り出す方法はあるのでしょうか?

vbaのサンプルを作ってみましたが、
やはり去年も2013年になってしまうようです。

Sub Sample()
Dim str As String

str = "5月24日(金)" '2013年
str = Left(str, Len(str) - 3)
str = CDate(str)

str = "5月24日(木)" '2012年
str = Left(str, Len(str) - 3)
str = CDate(str)

End Sub


ご教授よろしくお願いします。

A 回答 (6件)

例えばA列にお示しのようなデータが文字列として入力されているとしたら、その日付をB列に2013/5/24のように表示させるためには次のようなマクロにしたら良いでしょう。



Sub Sample()
Dim str As String
Dim m, n, x, y, d, Mo, i As Integer
Dim Da, Tye As Date
Dim w As String
m = Range("A65536").End(xlUp).Row
For n = 1 To m
If InStr(1, Range("A" & n), "月") > 0 Then
str = Range("A" & n)
x = InStr(1, str, "月")
y = InStr(1, str, "(")
d = InStr(1, str, "日")
w = Mid(str, y + 1, 1)
Mo = Left(str, x - 1)
Da = Mid(str, x + 1, d - x - 1)
For i = 2005 To 2013
Ye = DateSerial(i, Mo, Da)
We = WeekdayName(Weekday(Ye), True)
If We = w Then
Tye = DateSerial(i, Mo, Da)
Range("B" & n) = Tye
Exit For
End If
Next
End If
Next
End Sub
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/06/10 20:35

迂闊なことを云います、済みません


365日を1週間で割ると1日余ります。
加えて閏年では366日あります。

つまり4年で凡そ5日ずれる訳です
1年に直すと約365.242199日ずれる訳ですね。
(※注:ウィキペディア「閏年」の項より抜粋)

直近の閏年を探し出す。
その年の指定日の曜日を調べる
(※注:去年が閏年ですよね、なので去年の5/24日は木曜日ですね)


期日の曜日とのずれが
曜日にして何日分ずれているかを調べる
(※注:まあ… 6日以内でしょうね)
ずれ日数が、Mod(1.242199n,7) + 1と一致するnを求めれば良い気がします。

気がするだけですが…  滝汗


お騒がせしました。
m(_ _)m
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/06/10 20:35

対象の期間を 100 年以内などに限定しない場合、グレゴリオ暦は 400 年の周期です。

うるう年の複雑なルールのせいで、「全体の周期は」400 年です。

しかし、「ある年のある 1 日と」同じ月日で同じ曜日というだけなら、400 年も待たなくても、その間に繰り返し登場してくるのですね。No.2 さん、No.3 のおっしゃるとおりです。

うるう年が問題にならない 1900 年~ 2100 年のうち Excel が日付と曜日を正しく計算できる「1900 年 3 月 1 日~ 2100 年 2 月 28 日」という範囲で計算する限りは、5 年、6 年、または 11 年の間隔で同じ月日・曜日となります。400 年という全体の周期は、この 3 種類の小さな間隔が周期的に組み合わさってできています。

つまりご質問の課題は、このままでは条件不足により、不可能です。

しかし例えば「同じ月日・曜日である日のうち最も新しい日」という条件であれば、No.1 さんのコードで求められますね。step -1 と exit for という記述があるので、最新の日のみとなります。1 年が 365 日くらい、同じ月日・曜日の日が現れる頻度が 11 年以内ならば、データ処理量的にも 4,000 行くらいですから、大したことではありませんね。
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/06/10 20:35

今日5月25日は土曜日ですが、2002年や2019年も同様でした。

万年カレンダー、で検索していただければわかるかと思いますが、曜日からだけでは年を確定することはできません。
なので、日付が順に並んでいることを前提に、日付から年を推定するとかいうのが現実的かと。
Sub Sample()
Dim str As String

str = "5月24日(木)" '2012年
str = Left(str, Len(str) - 3)
str = CDate("2012年" & str)

MsgBox (str)

End Sub

でやってみると、2012/05/24 になりますので、これを参考に、表を年ごとに分割してVBAを走らせてはどうでしょうか?あるいは、セルを1行増やして、そこに年を入れちゃうというのでもいいですが。
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/06/10 20:35

>曜日から西暦を割り出す方法



例えば、

5月24日が金曜日の年は?

として、2013年、と返ってこればいいのでしょうが、

さかのぼっていけば、2002年も1996年も該当しますので一意に決めることはできないでしょう。

そもそも、そのデータは「西暦を除いた日付情報が文字列」として入っている、ということですが、
では、それを使う人は、どのようにして西暦を判別しているのですか?

もしシートごとに年が違うのならば、別の方法になるでしょうし、
時系列に並んでいるだけならば、これまた別の方法になるでしょうし、
全くランダムに入っているというのは考えにくいかと思うのですが。
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/06/10 20:35

チカラワザでやっつけてもさほどの事ではないです。




A1以下に文字列が記入されているとして
sub macro1()
 dim h as range
 dim y as integer
 dim md as string
 dim w as string

 for each h in range("A1:A" & range("A65536").end(xlup).row)
  if h <> "" then
   w = strconv(right(h.value, 3), vbnarrow)
   md = left(h.value, len(h.value) - 3)

   for y = 2013 to 2003 step -1
    if format(cdate(y & "年" & md), "(aaa)") = w then
     h.offset(0, 1) = cdate(y & "年" & md)
     exit for
    end if
   next y
  end if
 next
end sub
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/06/10 20:35

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