通过Access VBA中的数据透视表传播数据

时间:2016-06-30 10:30:27

标签: sql vba ms-access pivot

考虑这样的一对多关系:

@protocol PublicInterface <NSObject>

@required
- (void)doSomething;

@end

@interface PrivateObject : NSObject<PublicInterface> @end
@implementation PrivateObject

- (void)doSomething {}

@end

@interface Proxy : NSObject

+ (id<PublicInterface>)sharedInstance;

- (instancetype)init NS_UNAVAIALBLE;

@end

@implementation Proxy

- (instancetype)init {
    @throw @"Use -sharedInstance instead.";
    return nil;
}

+ (id<PublicInterface>)sharedInstance {
    static id sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[PrivateObject alloc] init];
    });
    return sharedInstance;
}

@end

使用这样的一些数据:

tblStuff
    - id

tblEntry
    - stuff_id
    - the_date
    - the_value

请注意,对于Stuff#42,有2个连续的条目(1月1日和8日),然后错过一周,然后是另一个条目。

我需要显示每个stuff_id the_date the_value -------- -------- --------- 42 01-Jan-1920 14 42 08-Jan-1920 12 42 22-Jan-1920 7 99 15-Mar-1920 18 99 22-Mar-1920 17 ,其条目分布在特定数量的列中,按Stuff展开。例如:

我需要以某种方式显示这样:

the_date

这可能吗?这些列表示自第一个id week1 week2 week3 week4 week5 -- ----- ----- ----- ----- ----- 42 14 12 7 99 18 17 以来的周数,每个Entry可能会有所不同。我不熟悉这样的数据转换 - 我应该从哪里开始?

非常感谢任何帮助。

修改

准确地说将有194周&#34;周&#34;列。我无法重新设计数据库,这是我必须使用的。

3 个答案:

答案 0 :(得分:1)

考虑建立一个每周数字表,其中包含从第一周到第194周开始的每个stuff_id周。您可以使用循环中传入参数的操作查询在VBA中构建它:

Public Sub WeekNumberTable()
    Dim db As Database
    Dim qdef As QueryDef
    Dim strSQL As String
    Dim i As Integer

    Set db = CurrentDb

    ' MAKE TABLE TO INITIATE FIRST WEEK
    strSQL = "SELECT stuff_ID, Min(the_date) As entry_date,  'week1' As week_number" _
         & " INTO tblEntryWeekNumber" _
         & " FROM tblEntry" _
         & " GROUP BY stuff_ID"

    db.Execute strSQL, dbFailOnError

    ' PREPARE SQL STRING
    strSQL = "PARAMETERS DayAdd Long, WeekNumber Text(255);" _
        & " INSERT INTO tblEntryWeekNumber (stuff_ID, entry_date, week_number)" _
        & " SELECT stuff_ID, Min(the_date) + [DayAdd], [WeekNumber] As week_number" _
        & " FROM tblEntry" _
        & " GROUP BY stuff_ID"

    ' LOOP THROUGH ALL WEEKS ITERATIVELY FOR EACH STUFF_ID
    For i = 1 To 194
       Set qdef = db.CreateQueryDef("", strSQL)

       qdef!DayAdd = 7 * i
       qdef!WeekNumber = "week" & i
       qdef.Execute , dbFailOnError
    Next i

    Set qdef = Nothing 
    Set db = Nothing
End Sub

构建此tabe后,将其连接到原始tblEntry数据并应用交叉表查询:

TRANSFORM Sum(t.the_value) AS SumOfthe_value
SELECT w.stuff_id
FROM tblEntryWeekNumber w
LEFT JOIN  tblEntry t ON (w.stuff_id = t.stuff_ID) 
AND (w.entry_date = t.the_date)
GROUP BY w.stuff_id
PIVOT w.week_number;

或者在 stuff_id the_date / entry_date 上连接表后的Crosstab查询设计视图中:

   Field: stuffId           the_value      weekNumber
   Table: tblWeekNumber     tblEntry       tblWeekNumber
   Total: Group By          Sum            Group By
Crosstab: Row Heading       Value          Column Heading
    Sort:
Criteria:
      or:

<强>输出

stuff_id    week1   week2   week3   week4   week5   week6
42             14      12               7       
99             18      17       

答案 1 :(得分:0)

听起来您需要cross tab查询。

enter image description here

我已从Office支持网站(上面的链接)中获取这些说明。此方法使用查询向导。别担心,它并不像长指示所暗示的那么复杂!

  

在“创建”选项卡上的“其他”组中,单击“查询向导”。

     

在“新建查询”对话框中,单击“交叉表查询向导”,然后单击“确定”   单击“确定”。

     

“交叉表查询向导”启动。

     

在向导的第一页上,选择您的表或查询   想用来创建交叉表查询。

     

在下一页上,选择包含您的值的字段   想用作行标题。

     

您最多可以选择三个字段作为行标题来源,但是   您使用的行标题越少,交叉表数据表就越容易   将会阅读。

     

如果您选择多个字段来提供行标题,请输入   您选择的字段确定您的默认顺序   结果排序。

     

在下一页上,选择包含您的值的字段   想用作列标题。

     

通常,您应该选择包含少量值的字段   帮助您轻松阅读结果。例如,使用一个字段   只有少数可能的值(如性别)可能比较好   使用可包含许多不同值(例如年龄)的字段。

     

如果您选择用于列标题的字段具有   日期/时间数据类型,向导添加一个步骤,让您指定方式   将日期分组为间隔,例如月或季。

     

如果为列标题选择日期/时间字段,则显示下一页   向导会要求您指定用于对日期进行分组的时间间隔。   您可以指定年,季度,月,日或日期/时间。如果你这样做   不为列标题选择日期/时间字段,向导会跳过   这个页面。

     

在下一页上,选择要用于计算的字段和函数   汇总值。您选择的字段的数据类型确定   哪些功能可用。

     

在同一页面上,选中或清除是,包含行总和复选框   包括或排除行和。

     

如果包含行总和,则交叉表查询还有一行   标题使用与字段值相同的字段和函数。   包括行和,插入一个总结的行   剩下的专栏。例如,如果您的交叉表查询计算   按地点和性别划分的平均年龄(性别列标题),   附加列计算所有地点的平均年龄   性别。

     

您可以更改用于生成行总和的函数   在“设计”视图中编辑交叉表查询。

     

在向导的下一页上,键入查询的名称,然后   指定是要查看结果还是修改查询   设计。

您也可以使用设计器手动创建这些查询,但我建议您最初几次使用该向导。

答案 2 :(得分:0)

不需要VBA。您需要Crosstab query

首先从您的表中创建一个基本查询,使用DatePart("ww", ...)来计算周数,并将其连接到&#34;周&#34;。
请务必使用firstdayofweekfirstweekofyear的正确参数,具体取决于您所在的国家/地区。在查询中,您必须使用数字,常数在那里不可用。

如果您想要194周的列,则还需要将添加到该字符串。

然后在该查询上运行交叉表向导。

在生成的查询中,切换到SQL视图。在那里你可以添加

PIVOT week_string IN ("week1", "week2", ...)

获取所有周数,即使几周内没有数据 见TRANSFORM statement