Extract years between two dates

koolwaters

Active Member
Joined
May 16, 2007
Messages
403
Hi,

I need to extract the years between two dates.

For example:

Start Date 2010-09-07
End Date 2014-08-30

The number of years between the Start Date and End Date are four.

As part of my query result, I need to see only the years between these two dates. So I would see,

2011 2012 2013 2014

If I have
Start Date 2010-09-07
End Date 2013-08-30

I need to see 2011 2012 2013

I hope that someone can assist.

Thanks in advance.
 
you need to change the insert statement

Code:
        sSQL = "Insert Into " & sTempTableName & "(ApplicationID, EmployeeID, StartDate, EndDate, AmountApproved, " & sYearFlds & ")" _
             & "Values (" & .Fields("ApplicationID").Value & ", [B][SIZE=5][COLOR=red]'[/COLOR][/SIZE][/B]" & .Fields("EmployeeID").Value & "[B][SIZE=5][COLOR=red]'[/COLOR][/SIZE][/B], #" & .Fields("StartDate").Value & "#, #" & .Fields("EndDate").Value & "#, '" & .Fields("AmountApproved").Value & "', " & sAmount & ")"

otherwise the insert will see the data as a number.
 
Upvote 0

Excel Facts

Remove leading & trailing spaces
Save as CSV to remove all leading and trailing spaces. It is faster than using TRIM().
I was trying my best to figure it out on my own but after several hours, I have decided to concede defeat and ask for assistance.

The Department field is not in tblApplication. It is in a table called tblStaffList. The EmployeeID is in tblApplication and there is a relationship between tblApplication and tblStaffList.

The code works fine but when I attempt to open the query that is created via the CreateDynamicQuery code, it prompts for the Segment.

So instead of:
Code:
SQL_Application = "Select * from tblApplication"

I need to select all of the fields in the application table as well as Department from tblStaffList.

Thanks again for your help
 
Upvote 0
In addition to the post above, I also need to create another table and query.

Using the code provided previously, I was able to create the table, which works fine.

No problem.

Code:
Option Compare Database
Option Explicit

Public Function SQL_ABSYears() As String
Const sTableName As String = "tblApplication"
SQL_ABSYears = "SELECT Min(StartDate) AS FirstStartDate, Max(EndDate) AS LastEndDate " _
             & "FROM " & sTableName
End Function

Public Function SQL_Application() As String
    SQL_Application = "Select * from tblApplication"
End Function

Public Sub CreateApplicationsForApprovalTable()
Dim dbs As DAO.Database
Dim rs As DAO.Recordset
Dim tdf As DAO.TableDef
Dim sSQL As String
Const sTempTableName As String = "ttblApplicationsForApproval"
Dim sYears() As String
Dim sYearFlds As String
Dim iFYear As Integer
Dim iLYear As Integer
Dim iCnt As Integer
Dim sAmounts() As String
Dim sAmount As String
Set dbs = CurrentDb
'Delete temptable if exists
For Each tdf In dbs.TableDefs
    If tdf.Name = sTempTableName Then dbs.TableDefs.Delete sTempTableName
Next tdf
'Fetch the absolute first date and last date
Set rs = dbs.OpenRecordset(SQL_ABSYears)
With rs
    If Not .EOF And Not .BOF Then
        .MoveFirst
        iFYear = Year(.Fields("FirstStartDate").Value) ' + 1
        iLYear = Year(.Fields("LastEndDate").Value)
    Else
        MsgBox "No data found", vbExclamation
        Exit Sub
    End If
    .Close
End With
'Create array holding all years between startdate and enddate
'- Amt in (US$)"
For iCnt = 0 To iLYear - iFYear '- 1
    ReDim Preserve sYears(iCnt)
    sYears(iCnt) = "[" & (iFYear + iCnt) & " - Amt in (US$)] Double"
Next iCnt
'Join years for create table sql
sYearFlds = Join(sYears, ", ")
sYearFlds = "ApplicationID Long, EmployeeID Text, StartDate DateTime, EndDate DateTime, AmountApproved Currency, " & sYearFlds
'create the temptable and index
sSQL = "Create Table " & sTempTableName & " (" & sYearFlds & ")"
dbs.Execute sSQL
sSQL = "CREATE UNIQUE INDEX [PrimaryKey] ON " & sTempTableName & " ([ApplicationID])  WITH PRIMARY DISALLOW NULL "
dbs.Execute sSQL
'Section to append data from Application to forecast
Set rs = dbs.OpenRecordset(SQL_Application)
With rs
    .MoveFirst
    Do Until .EOF
    
        'First determine the years to forecast
        sYearFlds = vbNullString
        ReDim sYears(0)
        ReDim sAmounts(0)
        
        iFYear = Year(.Fields("StartDate").Value) + 1
        iLYear = Year(.Fields("EndDate").Value)
        If iFYear > iLYear Then iFYear = iFYear - 1
            
        'create array for years to append
        For iCnt = 0 To iLYear - iFYear '- 1
            ReDim Preserve sYears(iCnt)
            ReDim Preserve sAmounts(iCnt)
            sYears(iCnt) = "[" & (iFYear + iCnt) & " - Amt in (US$)]"
            sAmounts(iCnt) = "'" & .Fields("AmountApproved").Value / (iLYear - (iFYear - 1)) & "'"
        Next iCnt
        sYearFlds = Join(sYears, ", ")
        sAmount = Join(sAmounts, ", ")
        'construct the insert statment
        sSQL = "Insert Into " & sTempTableName & "(ApplicationID, EmployeeID, StartDate, EndDate, AmountApproved, " & sYearFlds & ")" _
             & "Values (" & .Fields("ApplicationID").Value & ", '" & .Fields("EmployeeID").Value & "', #" & .Fields("StartDate").Value & "#, #" & .Fields("EndDate").Value & "#, '" & .Fields("AmountApproved").Value & "', " & sAmount & ")"
        'insert values into temptable
        dbs.Execute sSQL
    .MoveNext
    Loop
End With
End Sub

I need another dynamic query that has to be exported to Excel but I do not need the ApplicationID, EmployeeID, StartDate and EndDate in the result. In addition, I need to add some additional fields to this table from tblStaffList but I am having the same problem noted in my previous post with pulling the fields from multiple tables.

I also played around with your code to create the dynamic query. The query is being created, however when I attempt to open it after it is created, I get a message "Query must have at least one destination field" and when I open it in Design View, there is no table. This query is different to the first in that I do not need any totals for this one.

The fields displayed in the sheet below are pulled from tblStaffList and tblApplication.
Excel Workbook
ABCDEFGHIJKL
1DeptNamesGradeJob TitleBranchManagerManager SignoffDate Sent to ManagerDate Returned from ManagerDisciplineCourseDuration
2HRJane DoeAANorthJill DoeYes27-Feb-0923-Apr-09Information TechnologyMCSA4
3HRJane DoeABNorthJill DoeYes06-Jan-1114-Jan-11Information TechnologyMCSE1
4ITJohn DoeDCEastTom ThumbYes06-Jan-1114-Jan-11Information TechnologyCISSP1
qrptApplicationsForEMCApproval
Excel 2007
Excel Workbook
MNOPQRS
12010 - Amt in (US$)2011 - Amt in (US$)2012 - Amt in (US$)2013 - Amt in (US$)Overall Amount Requested (US$)Approve/DeclineReason for Decline
22,000.002,000.002,000.002,000.008,000.00Approved
36,000.008,000.00Approved
46,000.008,000.00Approved
qrptApplicationsForEMCApproval
Excel 2007

I hope that you can understand what I am trying to accomplish here. I will continue to play around with them to see if I get the desired result.

Thanks in advance for your help and all of the help you have provided so far. It is greatly appreciated.
 
Upvote 0
Ok, well a little different approach.
The temptable now only has one field besides the yearly amounts, it's PK ApplicationID when created. You don't actually need the other fields, because they are already in the Application table.

The idea is that you create a querydef with all the fields you need in your report/export. The routine creates a new querydef which joins the querydef you created with the dynamich table.
I assume that you know how to link tables in a query.

You'll need to create two module:

Mod 1

Code:
Option Compare Database
Option Explicit
Public Function SQL_ABSYears() As String
Const sTableName As String = "tblApplication"
SQL_ABSYears = "SELECT Min(StartDate) AS FirstStartDate, Max(EndDate) AS LastEndDate " _
             & "FROM " & sTableName
End Function
Public Function SQL_Application() As String
    SQL_Application = "Select * from tblApplication"
End Function
Public Sub CreateTempTable(ByVal sTblNameForeCast As String)
'Creates forecast table with fields:
'ApplicationID
'YearAmountFields for each year
Dim dbs As DAO.Database
Dim rs As DAO.Recordset
Dim tdf As DAO.TableDef
Dim sSQL As String
Dim sYears() As String
Dim sYearFlds As String
Dim iFYear As Integer
Dim iLYear As Integer
Dim iCnt As Integer
Dim sAmounts() As String
Dim sAmountValues As String
Set dbs = CurrentDb
'Delete temptable if exists
For Each tdf In dbs.TableDefs
    If tdf.Name = sTblNameForeCast Then dbs.TableDefs.Delete sTblNameForeCast
Next tdf
'Fetch the absolute first date and last date
Set rs = dbs.OpenRecordset(SQL_ABSYears)
With rs
    If Not .EOF And Not .BOF Then
        .MoveFirst
        iFYear = Year(.Fields("FirstStartDate").Value) ' + 1
        iLYear = Year(.Fields("LastEndDate").Value)
    Else
        MsgBox "No data found", vbExclamation
        Exit Sub
    End If
    .Close
End With
'Create array holding all years between startdate and enddate
For iCnt = 0 To iLYear - iFYear
    ReDim Preserve sYears(iCnt)
    sYears(iCnt) = "[" & (iFYear + iCnt) & sTrail & "] Double"
Next iCnt
'Join years for create table sql
sYearFlds = Join(sYears, ", ")
sYearFlds = "ApplicationID Long, " & sYearFlds
'create the temptable and index
sSQL = "Create Table " & sTblNameForeCast & " (" & sYearFlds & ")"
dbs.Execute sSQL
sSQL = "CREATE UNIQUE INDEX [PrimaryKey] ON " & sTblNameForeCast & " ([ApplicationID])  WITH PRIMARY DISALLOW NULL "
dbs.Execute sSQL
'Section to append data from Application to forecast
Set rs = dbs.OpenRecordset(SQL_Application)
With rs
    .MoveFirst
    Do Until .EOF
        'First determine the years to forecast
        sYearFlds = vbNullString
        ReDim sYears(0)
        ReDim sAmounts(0)
        iFYear = Year(.Fields("StartDate").Value) + 1
        iLYear = Year(.Fields("EndDate").Value)
        If iFYear > iLYear Then iFYear = iFYear - 1
        'create array for years to append
        For iCnt = 0 To iLYear - iFYear
            ReDim Preserve sYears(iCnt)
            ReDim Preserve sAmounts(iCnt)
            sYears(iCnt) = "[" & (iFYear + iCnt) & " - Amt in (US$)]"
            sAmounts(iCnt) = "'" & Round(.Fields("AmountApproved").Value / (iLYear - (iFYear - 1)), 2) & "'"
        Next iCnt
 
        sYearFlds = Join(sYears, ", ")
        sAmountValues = Join(sAmounts, ", ")
        'construct the insert statement
        sSQL = "Insert Into " & sTblNameForeCast & "(ApplicationID, " & sYearFlds & ")" _
             & "Values (" & .Fields("ApplicationID").Value & ", " & sAmountValues & ")"
        'insert values into temptable
        dbs.Execute sSQL
    .MoveNext
    Loop
End With
End Sub

Mod 2

Code:
Option Compare Database
Option Explicit
Public Const sTrail As String = " - Amt in (US$)" 'Trail string for field names yearly amounts
Public Sub MainCaller()
Const sLinkFieldOne As String = "ApplicationID"             'Fldname of PK of sTblNameForeCast
Const sTblNameForeCast As String = "ttblForeCast"           'Name of the created temptable
Const sLinkFieldTwo As String = "ApplicationID"             'Fldname of FK in sQueryToLinkName
Const sQueryToLinkName As String = "qDepartmentApplication" 'The query with all fields to display except the yearly amounts, and having the ApplicationID field in the select statement
Const sTempQueryName As String = "qForeCast"                'The name of the query to built
Dim blnSumAmounts As Boolean   'Switch to tell routine if the results need to be grouped and thus needing to sum and group fields.
Dim sSumThisFlds As String     'If you want a summarized result, then specifify the fields that need to be summed, except for the yearly dynamic fields
                               'All fields that are not summed, will automatically be the group fields
blnSumAmounts = True         'Switch to false if you don't want summarized results
sSumThisFlds = "AmountApproved"
BuiltTableWithQuery sQueryToLinkName, sTblNameForeCast, sLinkFieldOne, sLinkFieldTwo, sTempQueryName, blnSumAmounts, sSumThisFlds
End Sub
Public Sub BuiltTableWithQuery(ByVal sQueryToLinkName As String, _
                               ByVal sTblNameForeCast As String, _
                               ByVal sLinkFieldOne As String, _
                               ByVal sLinkFieldTwo As String, _
                               ByVal sTempQueryName As String, _
                               ByVal blnSumAmounts As Boolean, _
                               Optional ByVal sSumThisFlds As String = "")
 
'Routine that creates all entities
'1 create the forecast table
'2 create array with fieldnames
'3 create the querydef
Dim sAmtYFlds As String     'String to hold the dynamic fieldnames for comparison
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Dim iFldCnt As Integer
Dim sFields() As String
Dim sSumFields() As String
Dim sSQL As String
Dim s As String
Dim sSelFlds As String
Dim sGroupFlds As String
Dim sFlds As String
 
'Create the forecast table
CreateTempTable sTblNameForeCast
Set dbs = CurrentDb
'Get the fieldnames from the QueryToLink, ignore the link fields
Set qdf = dbs.QueryDefs(sQueryToLinkName)
iFldCnt = 0
For Each fld In qdf.Fields
 
        'Test if fld = sum field
        If blnSumAmounts And InStr(1, sSumThisFlds, fld.Name, vbTextCompare) <> 0 Then 'It's a sum field
            ReDim Preserve sFields(iFldCnt)
            sFields(iFldCnt) = "Sum([" & fld.Name & "]) as [Total " & fld.Name & "]"
            iFldCnt = iFldCnt + 1
        ElseIf fld.Name = sLinkFieldOne Or fld.Name = sLinkFieldTwo Then
            'Ignore field
        Else
            ReDim Preserve sFields(iFldCnt)
            sFields(iFldCnt) = fld.Name
            If blnSumAmounts Then sGroupFlds = sGroupFlds & ", " & fld.Name
 
            iFldCnt = iFldCnt + 1
        End If
Next fld
Set tdf = dbs.TableDefs(sTblNameForeCast)
'load all amtFlds from function
sAmtYFlds = sAmountYearFields
'test if current fieldname is in the sAmtYFlds string
'extract year amount fieldnames from tempforecast into array
'This is to eliminate all fields other than the dynamic fields
For Each fld In tdf.Fields
        If InStr(1, sAmtYFlds, fld.Name, vbTextCompare) > 0 Then
        ReDim Preserve sFields(iFldCnt)
            If blnSumAmounts Then
                sFields(iFldCnt) = "Sum([" & fld.Name & "]) as [Total " & fld.Name & "]"
                iFldCnt = iFldCnt + 1
            Else
                sFields(iFldCnt) = "[" & fld.Name & "]"
                iFldCnt = iFldCnt + 1
            End If
        End If
Next fld
sSelFlds = Join(sFields, ", ")
sSQL = SQL_JoinTwoTbls(sQueryToLinkName, sTblNameForeCast, sLinkFieldOne, sLinkFieldTwo, sSelFlds, Mid(sGroupFlds, 3))
'test if the query already exists, if so delete
    For Each qdf In dbs.QueryDefs
        If qdf.Name = sTempQueryName Then dbs.QueryDefs.Delete qdf.Name
    Next qdf
 
Set qdf = dbs.CreateQueryDef(sTempQueryName, sSQL)
End Sub
Public Function sAmountYearFields() As String
'creates a string with all possible values for dynamic field name regarding amounts using the const sTrail
'result = 2000/../2100 - Amt in (US$)
Dim sY(100) As String '100 years forward, if you still use this system by then, maybe it's time to update
Dim sFlds As String   'string for result
Dim yCnt As Long      'counter for years
Const iFY As Long = 2000 'starting year
For yCnt = 0 To UBound(sY)
    sY(yCnt) = iFY + yCnt & sTrail
Next yCnt
sAmountYearFields = Join(sY, ", ")
End Function
Public Function SQL_JoinTwoTbls(ByVal sTblOne As String, _
                                ByVal sTblTwo As String, _
                                ByVal sJoinFldOne As String, _
                                ByVal sJoinFldTwo As String, _
                                ByVal sSelFlds As String, _
                                Optional ByVal sGroupFlds As String)
 
'String function which creates a join between two tables
'Within this context, a table can also be a queryDef
Dim sSQL As String
If Len(sGroupFlds) <> 0 Then
    sGroupFlds = "Group By " & sGroupFlds
End If
sSQL = "Select " & sSelFlds & " " _
      & "FROM " & sTblOne & " INNER JOIN " & sTblTwo & " ON " & sTblOne & "." & sJoinFldOne & " = " & sTblTwo & "." & sJoinFldTwo & " " _
      & sGroupFlds
 
SQL_JoinTwoTbls = sSQL
End Function

I tried to make it as readable as possible, but of course you're free to ask any question. You only need to change the variables in the mainCaller sub
 
Last edited:
Upvote 0
Do I use these modules instead of the one in my previous post?

At this point I may seem a bit daft but I have been at this from just after 6 this morning and I don't seem to be thinking straight any more.
 
Upvote 0
Yess, these replace the previous one.
So basically all you need to do is:
Copy the two modules
Create a query with the fields you want to display and of course the ApplicationID.
Put the name of this query into the mainCaller for const sQueryToLinkName, and then run mainCaller.
 
Upvote 0
Ok, here is the first module which creates my table ttblApplicationsForEMCApproval. When I open this table, it is correct and have the ApplicationID and the columns with the different years. That part I understand.

I also added this line as it was not in the new module.

Code:
Const sTempTableName As String = "ttblApplicationsForEMCApproval"

Code:
Option Compare Database
Option Explicit

Public Function SQL_ABSYears() As String
Const sTableName As String = "tblApplication"
SQL_ABSYears = "SELECT Min(StartDate) AS FirstStartDate, Max(EndDate) AS LastEndDate " _
             & "FROM " & sTableName
End Function

Public Function SQL_Application() As String
    SQL_Application = "Select * from tblApplication"
End Function

Public Sub CreateTempTable(ByVal sTblNameForeCast As String)
'Creates forecast table with fields:
'ApplicationID
'YearAmountFields for each year
Dim dbs As DAO.Database
Dim rs As DAO.Recordset
Dim tdf As DAO.TableDef
Dim sSQL As String
Const sTempTableName As String = "ttblApplicationsForEMCApproval"
Dim sYears() As String
Dim sYearFlds As String
Dim iFYear As Integer
Dim iLYear As Integer
Dim iCnt As Integer
Dim sAmounts() As String
Dim sAmountValues As String
Set dbs = CurrentDb
'Delete temptable if exists
For Each tdf In dbs.TableDefs
    If tdf.Name = sTblNameForeCast Then dbs.TableDefs.Delete sTblNameForeCast
Next tdf
'Fetch the absolute first date and last date
Set rs = dbs.OpenRecordset(SQL_ABSYears)
With rs
    If Not .EOF And Not .BOF Then
        .MoveFirst
        iFYear = Year(.Fields("FirstStartDate").Value) ' + 1
        iLYear = Year(.Fields("LastEndDate").Value)
    Else
        MsgBox "No data found", vbExclamation
        Exit Sub
    End If
    .Close
End With
'Create array holding all years between startdate and enddate
For iCnt = 0 To iLYear - iFYear
    ReDim Preserve sYears(iCnt)
    sYears(iCnt) = "[" & (iFYear + iCnt) & sTrail & "] Double"
Next iCnt
'Join years for create table sql
sYearFlds = Join(sYears, ", ")
sYearFlds = "ApplicationID Long, " & sYearFlds
'create the temptable and index
sSQL = "Create Table " & sTblNameForeCast & " (" & sYearFlds & ")"
dbs.Execute sSQL
sSQL = "CREATE UNIQUE INDEX [PrimaryKey] ON " & sTblNameForeCast & " ([ApplicationID])  WITH PRIMARY DISALLOW NULL "
dbs.Execute sSQL
'Section to append data from Application to forecast
Set rs = dbs.OpenRecordset(SQL_Application)
With rs
    .MoveFirst
    Do Until .EOF
        'First determine the years to forecast
        sYearFlds = vbNullString
        ReDim sYears(0)
        ReDim sAmounts(0)
        iFYear = Year(.Fields("StartDate").Value) + 1
        iLYear = Year(.Fields("EndDate").Value)
        If iFYear > iLYear Then iFYear = iFYear - 1
        'create array for years to append
        For iCnt = 0 To iLYear - iFYear
            ReDim Preserve sYears(iCnt)
            ReDim Preserve sAmounts(iCnt)
            sYears(iCnt) = "[" & (iFYear + iCnt) & " - Amt in (US$)]"
            sAmounts(iCnt) = "'" & Round(.Fields("AmountApproved").Value / (iLYear - (iFYear - 1)), 2) & "'"
        Next iCnt
 
        sYearFlds = Join(sYears, ", ")
        sAmountValues = Join(sAmounts, ", ")
        'construct the insert statement
        sSQL = "Insert Into " & sTblNameForeCast & "(ApplicationID, " & sYearFlds & ")" _
             & "Values (" & .Fields("ApplicationID").Value & ", " & sAmountValues & ")"
        'insert values into temptable
        dbs.Execute sSQL
    .MoveNext
    Loop
End With
End Sub

I made the necessary changes in the second module. In the Main Caller, ttblApplicationsForEMCApproval is my temporary table that has been created in the previous module. qryApplication is the query I have created that pulls the fields need from the various tables. qryApplicationsForEMCApproval is the name of the query I need created.

How do I call this module in the previous module?

Code:
Option Compare Database
Option Explicit

Public Const sTrail As String = " - Amt in (US$)" 'Trail string for field names yearly amounts

Public Sub MainCaller()
Const sLinkFieldOne As String = "ApplicationID"             'Fldname of PK of sTblNameForeCast
Const sTblNameForeCast As String = "ttblApplicationsForEMCApproval"           'Name of the created temptable
Const sLinkFieldTwo As String = "ApplicationID"             'Fldname of FK in sQueryToLinkName
Const sQueryToLinkName As String = "qryApplication" 'The query with all fields to display except the yearly amounts, and having the ApplicationID field in the select statement
Const sTempQueryName As String = "qryApplicationsForEMCApproval"                'The name of the query to built
Dim blnSumAmounts As Boolean   'Switch to tell routine if the results need to be grouped and thus needing to sum and group fields.
Dim sSumThisFlds As String     'If you want a summarized result, then specifify the fields that need to be summed, except for the yearly dynamic fields
                               'All fields that are not summed, will automatically be the group fields
blnSumAmounts = True         'Switch to false if you don't want summarized results
sSumThisFlds = "AmountApproved"
BuiltTableWithQuery sQueryToLinkName, sTblNameForeCast, sLinkFieldOne, sLinkFieldTwo, sTempQueryName, blnSumAmounts, sSumThisFlds
End Sub

Public Sub BuiltTableWithQuery(ByVal sQueryToLinkName As String, _
                               ByVal sTblNameForeCast As String, _
                               ByVal sLinkFieldOne As String, _
                               ByVal sLinkFieldTwo As String, _
                               ByVal sTempQueryName As String, _
                               ByVal blnSumAmounts As Boolean, _
                               Optional ByVal sSumThisFlds As String = "")
 
'Routine that creates all entities
'1 create the forecast table
'2 create array with fieldnames
'3 create the querydef
Dim sAmtYFlds As String     'String to hold the dynamic fieldnames for comparison
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Dim iFldCnt As Integer
Dim sFields() As String
Dim sSumFields() As String
Dim sSQL As String
Dim s As String
Dim sSelFlds As String
Dim sGroupFlds As String
Dim sFlds As String
 
'Create the forecast table
CreateTempTable sTblNameForeCast
Set dbs = CurrentDb
'Get the fieldnames from the QueryToLink, ignore the link fields
Set qdf = dbs.QueryDefs(sQueryToLinkName)
iFldCnt = 0
For Each fld In qdf.Fields
 
        'Test if fld = sum field
        If blnSumAmounts And InStr(1, sSumThisFlds, fld.Name, vbTextCompare) <> 0 Then 'It's a sum field
            ReDim Preserve sFields(iFldCnt)
            sFields(iFldCnt) = "Sum([" & fld.Name & "]) as [Total " & fld.Name & "]"
            iFldCnt = iFldCnt + 1
        ElseIf fld.Name = sLinkFieldOne Or fld.Name = sLinkFieldTwo Then
            'Ignore field
        Else
            ReDim Preserve sFields(iFldCnt)
            sFields(iFldCnt) = fld.Name
            If blnSumAmounts Then sGroupFlds = sGroupFlds & ", " & fld.Name
 
            iFldCnt = iFldCnt + 1
        End If
Next fld
Set tdf = dbs.TableDefs(sTblNameForeCast)
'load all amtFlds from function
sAmtYFlds = sAmountYearFields
'test if current fieldname is in the sAmtYFlds string
'extract year amount fieldnames from tempforecast into array
'This is to eliminate all fields other than the dynamic fields
For Each fld In tdf.Fields
        If InStr(1, sAmtYFlds, fld.Name, vbTextCompare) > 0 Then
        ReDim Preserve sFields(iFldCnt)
            If blnSumAmounts Then
                sFields(iFldCnt) = "Sum([" & fld.Name & "]) as [Total " & fld.Name & "]"
                iFldCnt = iFldCnt + 1
            Else
                sFields(iFldCnt) = "[" & fld.Name & "]"
                iFldCnt = iFldCnt + 1
            End If
        End If
Next fld
sSelFlds = Join(sFields, ", ")
sSQL = SQL_JoinTwoTbls(sQueryToLinkName, sTblNameForeCast, sLinkFieldOne, sLinkFieldTwo, sSelFlds, Mid(sGroupFlds, 3))
'test if the query already exists, if so delete
    For Each qdf In dbs.QueryDefs
        If qdf.Name = sTempQueryName Then dbs.QueryDefs.Delete qdf.Name
    Next qdf
 
Set qdf = dbs.CreateQueryDef(sTempQueryName, sSQL)
End Sub

Public Function sAmountYearFields() As String
'creates a string with all possible values for dynamic field name regarding amounts using the const sTrail
'result = 2000/../2100 - Amt in (US$)
Dim sY(100) As String '100 years forward, if you still use this system by then, maybe it's time to update
Dim sFlds As String   'string for result
Dim yCnt As Long      'counter for years
Const iFY As Long = 2000 'starting year
For yCnt = 0 To UBound(sY)
    sY(yCnt) = iFY + yCnt & sTrail
Next yCnt
sAmountYearFields = Join(sY, ", ")
End Function

Public Function SQL_JoinTwoTbls(ByVal sTblOne As String, _
                                ByVal sTblTwo As String, _
                                ByVal sJoinFldOne As String, _
                                ByVal sJoinFldTwo As String, _
                                ByVal sSelFlds As String, _
                                Optional ByVal sGroupFlds As String)
 
'String function which creates a join between two tables
'Within this context, a table can also be a queryDef
Dim sSQL As String
If Len(sGroupFlds) <> 0 Then
    sGroupFlds = "Group By " & sGroupFlds
End If
sSQL = "Select " & sSelFlds & " " _
      & "FROM " & sTblOne & " INNER JOIN " & sTblTwo & " ON " & sTblOne & "." & sJoinFldOne & " = " & sTblTwo & "." & sJoinFldTwo & " " _
      & sGroupFlds
 
SQL_JoinTwoTbls = sSQL
End Function
 
Upvote 0

Forum statistics

Threads
1,224,522
Messages
6,179,297
Members
452,903
Latest member
Knuddeluff

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top