0

我正在使用如下表,其中有被分解为任务的项目,并且一个任务可能会出现不止一次。我的目标是获得同一任务的所有小时数的总和,例如任务 1 的总小时数 = 33 小时。

Project NameTask NameHours
Project 1      Task 1      4      
Project 1      Task 1      7      
Project 1      Task 1      4      
Project 1      Task 1      7      
Project 1      Task 1      4      
Project 1      Task 1      7      
Project 1      Task 2      4      
Project 1      Task 2      3      
Project 1      Task 2      15    
Project 1      Task 2      3      
Project 1      Task 2      4      
Project 1      Task 3      3      
Project 1      Task 3      4      
Project 1      Task 3      3      
Project 2      Task 1      7      
Project 2      Task 1      4      
Project 2      Task 1      3      
Project 2      Task 4      4      
Project 2      Task 4      7      
Project 2      Task 4      4      
Project 2      Task 4      3      
Project 2      Task 5      3      
Project 2      Task 5      3      
Project 2      Task 5      4      

这是我的目标输出:

Project 1Hours
Task 1      33      
Task 2      29      
Task 3      10      

Project 2Hours
Task 1      14      
Task 4      15      
Task 5      10      

该表是按项目名称排序的,它们也是唯一的名称,但是任务可能不是唯一的,例如任务 1 可能出现在项目 1 和项目 2 中,但应该只为项目 1 合计,其中项目名称是项目 1。

几天来,我一直在使用 powershell 尝试获得该输出,但无济于事。Powershell 可能有点不正统,所以我认为 vb 是答案。我在vb方面没有太多经验,因此非常感谢任何帮助。

4

1 回答 1

2

解决从表中选择和聚合数据问题的关键概念是 SQL、SELECT、WHERE 和 GROUP BY。从 VBA 或 VBScript 使用 SQL 意味着 ADO(连接,记录集)。VBScript 和 VBA 之间的语法差异只是一个小小的不便(从这里开始)。概念验证 VBScript:

Option Explicit

Const adClipString = 2

Dim goFS : Set goFS = CreateObject( "Scripting.FileSystemObject" )

WScript.Quit demoMain()

Function demoMain()
  demoMain = 0 ' assume success

  Dim sDDir   : sDDir    = goFS.GetAbsolutePathName("..\Data\sumhours")
  Dim sFiNa   : sFiNa    = "hours.txt"
  Dim sFSpec  : sFSpec   = goFS.BuildPath(sDDir, sFiNa)
  goFS.CreateTextFile(sFSpec, True).WriteLine Join(Array( _
        "A;B;C" _
      , "1;100;10" _
      , "1;200;20" _
      , "1;100;10" _
      , "2;100;99" _
  ), vbCrLf)
  Dim sC      : sC       = "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & sDDir & ";"
  Dim oXDb    : Set oXDb = CreateObject("ADODB.Connection")
  oXDb.open sC
  WScript.Echo Join(Split("A B C"), vbTab)
  WScript.Echo oXDb.Execute("SELECT * FROM [" & sFiNa & "]").GetString(adClipString, , vbTab, vbCrLf)
  WScript.Echo oXDb.Execute("SELECT SUM(C) FROM [" & sFiNa & "] WHERE A = 1 AND B = 100").GetString(adClipString, , vbTab, vbCrLf)
  WScript.Echo oXDb.Execute("SELECT A, B, SUM(C) FROM [" & sFiNa & "] GROUP BY A, B").GetString(adClipString, , vbTab, vbCrLf)
  oXDb.Close

End Function ' demoMain

输出:

cscript 16504304.vbs
A       B       C
1       100     10
1       200     20
1       100     10
2       100     99

20

1       100     20
1       200     20
2       100     99

更新:

VBA'实施':

Option Explicit

' code.xls, accesses sumhours.xls
' Ref to ADO (2.8)

Sub Main()
  Dim oXDb As New ADODB.Connection
  Dim sSC: sSC = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\trials\SoTrials\answers\8328305\data\sumhours\sumhours.xls;Extended Properties=""Excel 8.0;HDR=YES;IMEX=1"""
  oXDb.Open sSC
  Debug.Print oXDb.Execute("SELECT SUM(C) FROM [Tbl1] WHERE A=1 AND B=100").GetString(2, 2, vbTab, vbCrLf)
  oXDb.Close
End Sub

Powershell“实施”:

$sSC = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\trials\SoTrials\answers\8328305\data\sumhours\sumhours.xls;Extended Properties="Excel 8.0;HDR=YES;IMEX=1"'
$oXDb = new-object -comobject ADODB.Connection 
$oXDb.Open($sSC)
echo $oXDb.Execute("SELECT A, B, SUM(C) FROM [Tbl1] GROUP BY A, B").GetString(2, -1, " ", "`n")
$oXDb.Close()

只是为了表明语法就是语法。

于 2013-05-12T10:22:01.690 回答