我正在创建一个报告,并希望根据YYYYWW
格式的日期字段(字符串)检索数据。我想过滤数据,以便使用4个不同的数据集检索当前月份,上个月,前一个月和之前的月份值。
例如:
201547 = November 2015
如何创建将字符串转换为月份名称和年份的计算成员?我想使用此值来过滤掉多维数据集中的数据。还有其他方法吗?
:1
答案 0 :(得分:1)
使用互联网上找到的资源组合,您可以找到所需的信息。
首先,您需要找到一年中第一周的第一天。这已由this answer确定为
DateAdd("d",
(-1) * (CInt(New DateTime(Year(Now), 1, 1).DayOfWeek) +
IIf(CInt(New DateTime(Year(Now), 1, 1).DayOfWeek) < DayOfWeek.Monday,
7,
0)
) + 1,
New DateTime(Year(Now), 1, 1))
这需要适应任何一年 - 不仅仅是当前的一年,从字符串中查找年份如下
CInt(Left(Parameters!myDate.Value,4))
现在,正如this resource中所述,您可以使用DateAdd
将您输入的年份的周数添加到一年中的第一个日期
=(DateAdd(DateInterval.WeekOfYear,
CInt(Right(Parameters!myDate.Value,2))-1,
<<FIRST_DAY_OF_YEAR>>)
然后,您希望使用Month
和MonthName
获取此日期月份的月份名称。将它们全部粉碎在一起会产生以下结果
=MonthName(Month(DateAdd(DateInterval.WeekOfYear,
CInt(Right(Parameters!myDate.Value,2))-1,
DateAdd("d",
(-1) * (CInt(New DateTime(CInt(Left(Parameters!myDate.Value,4)), 1, 1).DayOfWeek) +
IIf(CInt(New DateTime(CInt(Left(Parameters!myDate.Value,4)), 1, 1).DayOfWeek) < DayOfWeek.Monday,
7,
0)
) + 1,
New DateTime(CInt(Left(Parameters!myDate.Value,4)), 1, 1))
)))
这将获得间隔
的月份的文本值在同一文本框中创建一个新占位符,然后重复上述内容以查找年份
=Year(DateAdd(DateInterval.WeekOfYear, ...
(记得删除最后一个大括号,否则你会得到一个End of Statement预期错误。)
这个shoud给出你需要的东西,所以
201501 = December 2014
201547 = November 2015
201553 = December 2015
201622 = May 2016
如果这有帮助,或者如果您还有其他问题,请告诉我
答案 1 :(得分:1)
尝试添加计算字段并将其设置为此表达式:
datediff()
然后使用该字段过滤报告。
替换返回&#34; 201547&#34;
的字段的字符串=MonthName(Month(DateAdd("ww",CInt(MID("201547",5,LEN("201547")))
,DateSerial(CInt(LEFT("201547",4)),1,1)))) & " " & LEFT("201547",4)
更新:用于查询具有所需格式的已调用成员的MDX脚本:
我已使用以下MDX进行了测试:
=MonthName(Month(DateAdd("ww",
CInt(MID(Fields!YearWeek.Value,5,LEN(Fields!YearWeek.Value)))
,DateSerial(CInt(LEFT(Fields!YearWeek.Value,4)),1,1))))
& " " & LEFT(Fields!YearWeek.Value,4)
要在您的查询中使用它,请将WITH MEMBER [Measures].[month&year] AS
'FORMAT(DateAdd("ww",STRTOVALUE(MID("201547",5,LEN("201547"))) ,CDATE(DateSerial(LEFT("201547",4),1,1))),"MMMM") + " " + LEFT("201547",4)'
SELECT { [month&year] } ON COLUMNS
FROM [Your Cube]
替换为与您的多维数据集结构相对应的"201547"
:
[Dimension].[Attribute].MemberValue
在数据集中有此字段后,您可以使用参数轻松过滤值。
请告诉我这是否可以帮助您。
答案 2 :(得分:0)
第1部分:确定哪一天属于哪一周
ISO-8601声明了将日期转换为周数的国际标准,反之亦然。
ISO标准周从星期一开始。一年可以有52周或53周。
第1周开始时有4种方法确定:
- 这是1月份的大部分时间(4次或更多次)的第一周
- 第一天是最接近1月1日的星期一
- 它有1月4日。因此,最早可能的日期是12月29日至1月4日,即1月4日至10日
- 它有一年的第一个工作日 - 即不包括星期六,星期日和1月1日。
第2部分:Excel计算
此答案假设日期存储为6个字符的字符串。
首先确定它开始的一年中的哪一天。
1) Strip the first four characters from the string.`
=left(<cell containing the year+week string>, 4)
2) Prepend "1/1/" to it.
="1/1/"&left(<cell containing the year+week string>, 4)
3) Convert this string to an Excel date
=datevalue(<the last result>)
4) Determine the Weekday of the 1st day of that year.
=weekday(<the last result>)
5) Calculate the Excel date of the first Monday.
=if((<the last result>-4)<0,<the result of step 3>+8-<the last result>, <the result of step 3>+1-<the last result>)
6) Work out how many weeks on from that we are:
=right(<original 6 char year/week string>,2)
7) Convert 6) to a number
=value(<last result>)
8) Add that to the Monday of Week 1
=<result of step 5>+<result of step 7>*7
9) Convert this to a month number
=month(<last result>)
10) Convert this to a month name
=choose(<last result>,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
11) Add the year back on
=<lastresult>&" "&<result of 1>
这给出了包含当前编号周的星期一的月号。
如果单元格A1包含'201547
然后单元格B1应包含:
=CHOOSE(MONTH(IF((WEEKDAY(DATEVALUE("1/1/"&LEFT(A1,4)))-4)<0,DATEVALUE("1/1/"&LEFT(A1,4))+1-WEEKDAY(DATEVALUE("1/1/"&LEFT(A1,4))),DATEVALUE("1/1/"&LEFT(A1,4))+8-WEEKDAY(DATEVALUE("1/1/"&LEFT(A1,4))))+7*(VALUE(RIGHT(A1,2)))),"January","February","March","April","May","June","July","August","September","October","November","December")&" "&LEFT(A1,4)
如果A1包含201547,那么B1将返回“2015年11月”。
进一步考虑: 你可能想让它变得更加复杂,以便在星期一结束的一个月没有开始,其最后一个星期一作为月份的一部分计算。更一般地说,那个星期只计算一个月的一部分是该月的3天或更多天。或者其工作日的3个或更多时间是本月的一部分。
实际上,我会将计算出的月份和年份作为主键,将YYYYMM代码作为次要键进行排序。