如何根据可变数量的条件从Excel表中检索数据?


1

我有以下薪水数据,例如:

Country  State     2012  2013 -> 2027
=======  =====     ====  ====
China    Other     1000  1100
China    Shanghai  1310  1400
China    Tianjin   1450  1500
India    Orissa    1500  1600

所以现在在另一个Excel表格中我想要回答以下问题之一:

  1. 上海2013年的工资是多少?(答案是1400)
  2. 湖北省2012年的工资是多少?(由于未列出,请使用“其他” - 1000)
  3. 2013年中国的平均工资是多少?(答案是1333)
  4. 2012年中国的最高薪水是多少?(答案是天津)

因此,按照上面的优先顺序,我希望使用某种形式的查询在另一个Excel工作表中使用这些数字。我考虑了数据透视表,但我想知道是否有更好的更有效的方法来做到这一点?

我认为SQL适合这一点,但我并没有对此有所了解。一些Excel功能是非常优选的。还将赞赏关于这种查询的适当数据格式的建议。


1
“我认为SQL适合这一点,但我并没有克服” - 搞定它,这将是一个轻而易举的:)如果单元格是硬编码的,你能不能通过$ Sheet $引用它们?
戴夫

我很乐意学习SQL,但我必须与同事分享这个模型,是的,他们在技术上不是很倾向,或者有那么多时间!
Eshwar 2012年

:让你有4列我想通过unpivoting数据开始CountryStateYearSalary。然后将其设置为数据透视表并用于GETPIVOTDATA()提取所需的数据。
安迪特拉2017年

更好的是,使用数据库功能!
安迪·泰拉

Answers:


1

您的用例非常适合Excel的数据库功能。要使用它们,您首先需要取消数据的移动,以便每行对应数据中的一个观察值。这意味着你将有4列:CountryStateYearSalary

然后,您可以使用DGET()获取数据库中的特定条目和DAVERAGE()以获得平均值。数据库函数的标准需要以成对的单元格进行布局,其中过滤字段位于顶部,而要过滤的值位于其下方。这是一个有效的例子:

在此输入图像描述

单元格I10的公式与I9的公式相同,只是它使用了DAVERAGE。

  • I9进入=IFERROR(DGET($B$4:$E$12,$E$4,$G$4:$I$5),"")
  • I10进入=IFERROR(DAVERAGE($B$4:$E$12,$E$4,$G$4:$I$5),"")

IFERROR()周围确保DGET不显示#NUM!当你没有在第6行的所有三个输入中提供值时。这是因为如果你没有告诉它要过滤哪一年,它就找不到工资的单个值。


如果你想拥有一个灵活的参数数量,你可以建立一个标准列表,比如,DAVERAGE()通过使用动态的命名范围
Andy Terra,

0

我认为一种方法是命名列 - 例如,右键单击值为1400的单元格(2013年上海的工资)和 define name

然后,在另一个单元格中或者只是引用那个单元格 - 这样的美妙之处在于,如果移动该单元格并不重要,它将保留您想要的内容。


0

通过一些准备工作,这也可以在Excel中轻松完成。(尽管使用SQL可能更容易也更自然)。

准备:使用命名范围作为@Adam建议 - country对于国家,state对于州,我也以这种格式命名每年year2012

然后,您可以创建答案表

     A              B         C         D
1 salary in     Shanghai    2013    =IFERROR(INDEX(INDIRECT("year"&C1),MATCH(B1,state,0)),INDEX(INDIRECT("year"&C1),MATCH("Other",state,0)))
2 salary in     Hubei       2012    =IFERROR(INDEX(INDIRECT("year"&C2),MATCH(B2,state,0)),INDEX(INDIRECT("year"&C2),MATCH("Other",state,0)))
3 average       China       2013    =AVERAGEIF(country,B3,INDIRECT("year" & C3))
4 highest       China       2012    {=INDEX(state,MATCH(MAX(IF(country=B4,INDIRECT("year"&C4))),INDIRECT("year"&C4),0))}

这些行中的每一行都是动态的,因此您可以根据需要更改“问题”。需要注意的重要一点是,第4个(最高)公式是数组公式,需要CTRL+SHIFT+ENTER在输入时使用。

ps你对第3个问题的回答是错误的,2013年中国的平均工资应该是1333。


0

我同意Dave Rook的说法,那就是你应该使用SQL的地方。

也可以完全使用Excel公式(不是什么?)。这是如何:

首先,您需要一种解决每个列的方法。你有两个选择。

  1. 首先,(像Dave Rook建议的那样)直截了当,更“美丽”,就是定义命名范围。请确保,每个命名范围都足以包含所有未来记录(或使用某种动态命名范围)。不幸的是,它需要对每列进行一些点击,因此当您有100列时它不会缩放。

  2. 另一个选项(我更喜欢重型计算)是生成列范围地址字符串,例如=ADDRESS(ROW(C3);COLUMN(C3);4;;"sheet1") & ":" & ADDRESS(ROW(C3)-1+$A$2;COLUMN(C3);4)用于访问C存储在单元格中的记录数量的列上的数据A2。然后INDIRECT(),当您通常粘贴方法1中的命名范围时,通过在任何地方使用公式来解决范围。

一旦所有列(字段)都是命名范围,您就可以对它们执行所有类型的查找和引用任务。

例如:识别包含您将使用的单词“Shanghai”的记录数=MATCH("Shanghai";State;0),其中State是“State”列的命名范围。

一旦你有了记录号(让我们说它在单元格中X10,你可以获得有关薪水的信息)=INDEX(Salary;X10)

Excel公式中可以执行各种任务; 例如,您可以创建唯一值列表(或符合特定条件的值),您可以计算任何形式的总和/平均值。你甚至可以对它们进行排序(是的!)。

请注意,在我的语言环境中,我使用分号;作为参数分隔符(不是逗号)。英语国家通常使用,,在这种情况下使用我的公式,你需要更换所有;- > ,


1
我想你的意思MATCH不是MATH吗?而且我认为应该注意分号或逗号的使用取决于语言环境 - 通常它是逗号。
迈克尔

0

去找这个vba aproach,它应该没有太多的调整工作。错误处理可以更新,tho:

Private Sub get_money(byval country as string, byval city as string, byval year as string)
    if country == "" then country == "nope" end if
    if city == "" then city =="nope" end if
    if year == "" then year =="nope" end if
    if autofiltermode = true then autofiltermode = false

    dim all_columns as double
    all_columns = thisworkbook.activesheet.range("A1").currentregion.columns.count
    with thisworkbook.activesheet
        for cell_position = 3 to all_columns
            if .cells(1,cell_position) == year
                year_to_filter = cell_position
                cell_position = all_columns
            end if
        next cell_position
        .Range(.cells(1,1), .cells(1,all_columns)).AutoFilter Field:=1, Criteria1:=country, Operator:=xlFilterValues
        .Range(.cells(1,1), .cells(1,all_columns)).AutoFilter Field:=2, Criteria1:=city, Operator:=xlFilterValues
        .Range(.cells(1,1), .cells(1,all_columns)).AutoFilter Field:=cell_position, Criteria1:=year, Operator:=xlFilterValues 
    end with      
end sub
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.