2015-07-13 110 views
0

我有字段,其中有作为交货日期的名称,您可以在这里看到: extract of the table 我有大约75列这样。当我想计算P1值时,我有一个错误,因为它找不到该字段。顺便说一下,我的系数T1,T2(它们是日期),因此A和B的数值非常奇怪。还有就是代码:日期作为无法识别的字段的名称访问

Sub vcm_fc() 
    Dim db As Database, T As Date, longest As Integer, nearest_date As Date, rsb As DAO.Recordset, strsqlb As String 
    Dim strsqla As String, rsa As Recordset, maturity As Date, T1 As Date, T2 As Date, P1 As Double, P2 As Double 
    Dim a As Integer, B As Integer, j As Integer, rsc As DAO.Recordset, strqlc As String, settlementbis As String 
    Dim settlement As String, maturitybis As Date, ym As Integer, ymbis As Integer 
     Set db = CurrentDb() 
     T = DateSerial(2020, 8, 15) 
     nearest_date = DFirst("PricingDate", "fc_historical") 
     longest = DateDiff("m", nearest_date, T) 
     db.Execute "CREATE TABLE time_series " _ 
        & "(PricingDate CHAR);" 
     db.Execute " INSERT INTO time_series " _ 
      & "SELECT PricingDate " _ 
      & "FROM fc_historical " _ 
      & "ORDER BY PricingDate;" 
       For i = 1 To longest 
       db.Execute " ALTER TABLE time_series " _ 
        & "ADD COLUMN F_" & i & " Number;" 
       strsqla = "SELECT PricingDate, F_" & i & " FROM time_series ORDER BY PricingDate" 
       Set rsa = db.OpenRecordset(strsqla, dbOpenDynaset) 
       rsa.MoveFirst 
       rsa.Delete 'delete the first row which is blank when the time series table is created' 
       rsa.MoveFirst 
       While (Not rsa.EOF()) 
       rsa.Edit 
       maturity = DateAdd("m", i, rsa.Fields("PricingDate").Value) 
       ym = Year(maturity) - 2000 
       settlement = "1/" & Month(maturity) & "/" & ym 
       strsqlb = "SELECT Pricingdate, " & settlement & " FROM fc_historical ORDER BY PricingDate;" 
       Set rsb = db.OpenRecordset(strsqlb, dbOpenDynaset) 
       rsb.MoveLast 
       T1 = rsb.Fields("PricingDate").Value 
       maturitybis = DateAdd("m", i, maturity) 
       ymbis = Year(maturitybis) - 2000 
       settlementbis = "1/" & Month(maturitybis) & "/" & ymbis 
       strsqlc = "SELECT Pricingdate, " & settlementbis & " FROM fc_historical ORDER BY PricingDate;" 
       Set rsc = db.OpenRecordset(strsqlc, dbOpenDynaset) 
       rsc.MoveLast 
       T2 = rsc.Fields("PricingDate").Value 
       a = DateDiff("d", T1, rsa.Fields("PricingDate").Value) 
       B = DateDiff("d", rsa.Fields("PricingDate").Value, T2) 
       P1 = rsb.Fields(settlement).Value 
       P2 = rsc.Fields(settlementbis).Value 
       rsa.Fields("F_" & i) = (P1 * B + P2 * a)/(a + B) 
       rsa.Update 
       rsa.MoveNext 
       Wend 
     Next i 
End Sub 
+3

我不会那样设计表格 - 看起来完全反对关系数据库理论和规范化。取而代之的是3列 - PricingDate,OldFieldHeadingDate,Value。然后,您的表可以从表中SELECT Value FROM WHERE PricingDate =#somedate#AND OldFieldHeadingDate =#somedate#。您将在PricingDate中出现多个相同日期 - 也许可以使用PricingDate和OldFieldHeadingDate作为主键。数据库规则1 - 它不是电子表格。 :) –

+0

领域是两周前(周围)的结算日期和交易止损。然后这个想法是在交易停止之前(月份)为所有不同时期获得一个新的时间表。对于每个日期,新价格是在最近的交易日期+交易止损前的期间(我们保持固定)的加权平均价格。此外,我不只有3列,而是75列。然而,如果我明白了你的想法,我可以为结算日期创建一个索引,然后我可以计算新的价格,不是吗? –

+1

是的,索引将是第一个和第二个字段的组合 - 不需要75个字段,只需要三个字段。如果计算价格,您可以轻松编写查询以处理同一个表中较早的PricingDate/SettlementDate(?)记录。 –

回答

1

已添加为答案,以便我可以获取代码的格式。这段代码会把你的日期字段名称和它们作为记录值 - 你可能需要仔细研究fld.Name,以确保它不是美国日期格式(1月8日,1月9日等)。与该日期的价格。

Sub Put_Field_Names_As_Record_Values() 

    Dim DB As DAO.Database 
    Dim OldTable As DAO.TableDef 
    Dim fld As DAO.Field 

    Set DB = CurrentDb() 
    Set OldTable = DB.TableDefs("time_series") 

    DoCmd.SetWarnings False 
    For Each fld In OldTable.Fields 
     If IsDate(fld.Name) Then 
      Debug.Print fld.Name & " : " & SQLDate(fld.Name) 
      DoCmd.RunSQL "INSERT INTO MyNewTable (PricingDate, SettlementDate, Price) " & _ 
       "SELECT PricingDate," & SQLDate(fld.Name) & ", [" & fld.Name & "] FROM time_series" 
     End If 
    Next fld 
    DoCmd.SetWarnings True 

End Sub 

Function SQLDate(varDate As Variant) As String 
    'Purpose: Return a delimited string in the date format used natively by JET SQL. 
    'Argument: A date/time value. 
    'Note:  Returns just the date format if the argument has no time component, 
    '    or a date/time format if it does. 
    'Author:  Allen Browne. [email protected], June 2006. 
    If IsDate(varDate) Then 
     If DateValue(varDate) = varDate Then 
      SQLDate = Format$(varDate, "\#mm\/dd\/yyyy\#") 
     Else 
      SQLDate = Format$(varDate, "\#mm\/dd\/yyyy hh\:nn\:ss\#") 
     End If 
    End If 
End Function 

然后,您可以运行查询的表:

SELECT SUM(Price) 
FROM MyNewTable 
WHERE PricingDate<=#07/16/2014# AND SettlementDate=#01/08/2014# 

编辑:测试你的数据库的副本!
编辑2:手动创建MyNewTable并将PricingDate和SettlementDate设置为关键字段。

我已更新将字段名称转换为正确的日期 - http://allenbrowne.com/ser-36.html
在我的测试中,它将所有日期正确地转换为每月的第一个日期。

+0

所有日期均采用欧洲格式,因此该列在8月1日和9月1日开始。所有的定居点都是每个月的第一个。 –

+0

对于日期格式,我用下面的代码解决了我的pb:''SELECT PricingDate,#“&DateSerial(Year(fld.Name),Day(fld.Name),Month(fld.Name))& #,[“&fld.Name&”] FROM fc_historical WHERE [“&fld.Name&”] BETWEEN 0和10000000000000 ORDER BY PricingDate“ –

-1

使用正确格式化的日期表达式:

settlementbis = "#" & CStr(ymbis) & "/" & CStr(Month(maturitybis)) & "/1#" 

,做听达伦约正常化。

+0

我按照[这里]的说明尝试过(http://pauls-learningcurve.blogspot.co.uk/2013/12/ms-access-functions-domain-functions.html),但该错误依然存在。 –

+0

对不起,我想你是创建带有“日期”作为标题的列。正如其他人已经提到的那样,您需要彻底重新设计您的概念。访问不是电子表格。 – Gustav

相关问题