From: Dixie on
I have a problem using Dev Ashish's excellent module to concatenate the
results of a field from several records into one record.

I am using the code to concatenate certain awards onto a certificate at the
end of the year. I have the code working fine, except for the fact that
when I want to restrict the entries to awards between certain dates, even
though I can use the restriction in the query that shows the actual records,
when the fConcatChild function runs, it picks up all the entries, regardless
of the date restriction. I tried to run the table part as a qry rather than
a tbl, but no joy. I think the code inside Dev's module will need to get
have the date restriction in it. I need the type of restriction that is
WHERE Date >start date <End date.

Does anyone know how to do that within the module.
The code in that module is beyond my expertise.

The code I have is as follows:
***************************************
Function fConcatChild(strChildTable As String, _
strIDName As String, _
strFldConcat As String, _
strIDType As String, _
varIDvalue As Variant) _
As String
'Returns a field from the Many table of a 1:M relationship
'in a semi-colon separated format.
'
'Usage Examples:
' ?fConcatChild("Order Details", "OrderID", "Quantity", _
"Long", 10255)
'Where Order Details = Many side table
' OrderID = Primary Key of One side table
' Quantity = Field name to concatenate
' Long = DataType of Primary Key of One Side Table
' 10255 = Value on which return concatenated Quantity
'
Dim db As Database
Dim rs As Recordset
Dim varConcat As Variant
Dim strCriteria As String, strSQL As String
On Error GoTo Err_fConcatChild

varConcat = Null
Set db = CurrentDb
strSQL = "Select [" & strFldConcat & "] From [" & strChildTable & "]"
strSQL = strSQL & " Where "

Select Case strIDType
Case "String":
strSQL = strSQL & "[" & strIDName & "] = '" & varIDvalue & "'"
Case "Long", "Integer", "Double": 'AutoNumber is Type Long
strSQL = strSQL & "[" & strIDName & "] = " & varIDvalue
Case Else
GoTo Err_fConcatChild
End Select

Set rs = db.OpenRecordset(strSQL, dbOpenSnapshot)

'Are we sure that 'sub' records exist
With rs
If .RecordCount <> 0 Then
'start concatenating records
Do While Not rs.EOF
varConcat = varConcat & rs(strFldConcat) & vbCrLf
.MoveNext
Loop
End If
End With

'That's it... you should have a concatenated string now
'Just Trim the trailing ;
fConcatChild = Left(varConcat, Len(varConcat) - 2)

Exit_fConcatChild:
Set rs = Nothing: Set db = Nothing
Exit Function
Err_fConcatChild:
Resume Exit_fConcatChild
End Function
***************************

Apart from trying to get this module to do as I wish it, I had though of
using a maketable query to put the entries I wish to use into a temporary
table, then running this function on that data, but it would be nice to know
how to modify the module with a restriction.

TIA
Dixie
PS sorry about the length of this post.


From: pietlinden on
You have to pass the StartDate and EndDate into the function, so it
should look like this:

Function fConcatChild(strChildTable As String, _
strIDName As String, _
strFldConcat As String, _
strIDType As String, _
varIDvalue As Variant _
dtmStart As Date, _
dtmEnd As Date, _
As String
'--Function body (mostly omitted for brevity!)
End Function

then after this:

Select Case strIDType
Case "String":
strSQL = strSQL & "[" & strIDName & "] = '" & varIDvalue &
"'"
Case "Long", "Integer", "Double": 'AutoNumber is Type Long
strSQL = strSQL & "[" & strIDName & "] = " & varIDvalue
Case Else
GoTo Err_fConcatChild
End Select

You need to drop in the date filtering part of the WHERE clause
strSQL = strSQL & " AND [SomeDate] BETWEEN #" & dtmStart & "# AND #" &
dtmEnd &"#"

see? nothing to it, right?

From: Salad on
Dixie wrote:
> I have a problem using Dev Ashish's excellent module to concatenate the
> results of a field from several records into one record.
>
> I am using the code to concatenate certain awards onto a certificate at the
> end of the year. I have the code working fine, except for the fact that
> when I want to restrict the entries to awards between certain dates, even
> though I can use the restriction in the query that shows the actual records,
> when the fConcatChild function runs, it picks up all the entries, regardless
> of the date restriction. I tried to run the table part as a qry rather than
> a tbl, but no joy. I think the code inside Dev's module will need to get
> have the date restriction in it. I need the type of restriction that is
> WHERE Date >start date <End date.
>
> Does anyone know how to do that within the module.
> The code in that module is beyond my expertise.
>
> The code I have is as follows:
> ***************************************
> Function fConcatChild(strChildTable As String, _
> strIDName As String, _
> strFldConcat As String, _
> strIDType As String, _
> varIDvalue As Variant) _
> As String
> 'Returns a field from the Many table of a 1:M relationship
> 'in a semi-colon separated format.
> '
> 'Usage Examples:
> ' ?fConcatChild("Order Details", "OrderID", "Quantity", _
> "Long", 10255)
> 'Where Order Details = Many side table
> ' OrderID = Primary Key of One side table
> ' Quantity = Field name to concatenate
> ' Long = DataType of Primary Key of One Side Table
> ' 10255 = Value on which return concatenated Quantity
> '
> Dim db As Database
> Dim rs As Recordset
> Dim varConcat As Variant
> Dim strCriteria As String, strSQL As String
> On Error GoTo Err_fConcatChild
>
> varConcat = Null
> Set db = CurrentDb
> strSQL = "Select [" & strFldConcat & "] From [" & strChildTable & "]"
> strSQL = strSQL & " Where "
>
> Select Case strIDType
> Case "String":
> strSQL = strSQL & "[" & strIDName & "] = '" & varIDvalue & "'"
> Case "Long", "Integer", "Double": 'AutoNumber is Type Long
> strSQL = strSQL & "[" & strIDName & "] = " & varIDvalue
> Case Else
> GoTo Err_fConcatChild
> End Select
>
> Set rs = db.OpenRecordset(strSQL, dbOpenSnapshot)
>
> 'Are we sure that 'sub' records exist
> With rs
> If .RecordCount <> 0 Then
> 'start concatenating records
> Do While Not rs.EOF
> varConcat = varConcat & rs(strFldConcat) & vbCrLf
> .MoveNext
> Loop
> End If
> End With
>
> 'That's it... you should have a concatenated string now
> 'Just Trim the trailing ;
> fConcatChild = Left(varConcat, Len(varConcat) - 2)
>
> Exit_fConcatChild:
> Set rs = Nothing: Set db = Nothing
> Exit Function
> Err_fConcatChild:
> Resume Exit_fConcatChild
> End Function
> ***************************
>
> Apart from trying to get this module to do as I wish it, I had though of
> using a maketable query to put the entries I wish to use into a temporary
> table, then running this function on that data, but it would be nice to know
> how to modify the module with a restriction.
>
> TIA
> Dixie
> PS sorry about the length of this post.
>
>
I don't see where you are restricting by a date range. And the code
doesn't have any place for restricting it.

Dev's code puts in the name of the column to return from a table where
the ID = a key value passed.

If you know what the date range is, you could pass another argument to
the function. For example

'sample code prior to calling the function
Dim strTable As String
Dim strColumnToConcat As String
Dim strFieldNameOfKey As String
Dim strKeyValue As Variant
Dim strKeyType As String
Dim strDateRestrict As String

strTable = "Order Details"
strColumn = "Quantity"
strFieldNameOfKey = "OrderID"
strKeyValue = 10255
strKeyType = "Long"

***********
'Scenario 1: You have a from/To date on a form
'now we'll assume you have a FromDate and a ToDate on the form
'let's assume in the table the date field is called DateFld
'remember, date fields are surrounded by #
If Not IsNull(Me.FromDate) Then
strDateRestrict = "DateFld >= #" & Me.FromDate & "#"
Endif
If Not IsNull(Me.FromDate) And Not IsNull(Me.ToDate) Then
strDateRestrict = strDateRestrict & " And "
Endif
If Not IsNull(Me.FromDate) Then
strDateRestrict = strDateRestrict & _
"DateFld <= #" & Me.ToDate & "#"
Endif
********

***********
'Scenario 2: You have a From/To date variable
'if you didn't have a from/to date, this is how it would work
'with a variable. Again, the field in the table is assumed to
'be called DateFld
Dim datFrom As Date
Dim datTo As Date

'since the date fields have been dimmed, they are initialized
'to 12/30/1899 so check for that, not null
If Year(datFrom) <> 1899 Then
strDateRestrict = "DateFld >= #" & datFrom & "#"
Endif
If Year(datFrom) <> 1899 And Year(datFromDate) <> 1899 Then
strDateRestrict = strDateRestrict & " And "
Endif
If Year(datTo) <> 1899 Then
strDateRestrict = "DateFld <= #" & datTo & "#"
Endif
********

strTable = "Order Details"
strColumnToConcat = "Quantity"
strFieldNameOfKey = "OrderID"
strKeyValue = 10255
strKeyType = "Long"

fConcatChild(strTable, strFieldNameOfKeystrColumnToConcat, _
strKeyType, strKeyValue, strEDEatRestrict)


Now, the function needs to have the new argument and I'll call it
strDateFilter. Add it to the function.
Function fConcatChild(strChildTable As String, _
strIDName As String, _
strFldConcat As String, _
strIDType As String, _
varIDvalue As Variant,
strDateFilter As String) As String

Now you need to check for the date filter prior to opening the
recordset. If you passed something it it, add it to the SQL statement.
Change your above code to contain the following

If strDateFilter <> "" Tnen
strSQL = strSQL & " And " & strDateFilter
End If

Set rs = db.OpenRecordset(strSQL, dbOpenSnapshot)
From: Dixie on
Thank you Piet, with a little bit of work on the string in the query, this
is now working fine. Nothing to it? Maybe for you, but at least I can
follow how it works and was able to modify the query string to suit, so I
consider I learned something. Thanks for helping.

dixie


From: Dixie on
Scenario 1: was my scenario - the start and end date both on the form. Both
have default dates that would encompass the whole range of entries.
I have read through your post and I think I follow it. I'll put some time
into it over the weekend and finish it off. I have already looked briefly
at a similar method from Piet Linden and at this stage, it seems to work OK.
I will particulary look at your code to check that the restrictor has valid
data. I think I need to check for the case where the end date is earlier
than the start date.

Thanks for your help Salad. It is always good to know that such
knowledgeable people are willing to help people.

dixie