Hi Allen,
I think I've gotten to the last step. How do I include the column
heading string in the pivot clause? Here's what I have so far. I decided
to
try this with a report first as you mentioned. When I click the button on
my
form, I get the error "Property not Found" and DoCmd.OpenQuery ("qryCT")
is
highlighted. When I try to open the query directly it says "Does not
recognize [Property.Properties] as valid expression or feild name."
Thanks.
Marcie
Private Sub cmdRptDataCrossTab_Click()
If Me.FilterOn = False Then
MsgBox ("You have not selected any records. Please select" & vbCrLf
& "records by entering criteria and clicking " & "'Filter'" & ".")
GoTo ErrExit
Else
Dim strWhere As String
strWhere = Me.Filter
Dim CHsql As String
Dim strCH As String
Dim strQ As String
strQ = """"
strWhere = Replace(strWhere, "[Property]", "Data.Property")
strWhere = Replace(strWhere, "[MLO]", "Data.MLO")
strWhere = Replace(strWhere, "[TestMethod]", "Data.TestMethod")
strWhere = Replace(strWhere, "[RNumeric]", "Data.RNumeric")
strWhere = Replace(strWhere, "[RText]", "Data.RText")
strWhere = Replace(strWhere, "[Description]", "MLO.Description")
Debug.Print strWhere
'Build sql string for column headings of crosstab report.
strCH = "[Properties.Abbreviation] & " & strQ & vbCrLf & strQ & " &
[TestMethods.Abbreviation]"
CHsql = CHsql & "SELECT DISTINCT " & strCH & " AS ColumnHeadings "
CHsql = CHsql & "FROM (Properties INNER JOIN (TestMethods INNER
JOIN
Data ON TestMethods.Method = Data.TestMethod) ON "
CHsql = CHsql & "Properties.Property = Data.Property) INNER JOIN
PropertiesMethodsJunction ON (TestMethods.Method = "
CHsql = CHsql & "PropertiesMethodsJunction.JMethod) AND
(Properties.Property = PropertiesMethodsJunction.JProperty) "
CHsql = CHsql & "WHERE (" & strWhere & ") ORDER BY " & strCH & ";"
Debug.Print CHsql
'Build Crosstab Query SQL
Dim CTQsql As String
Dim CTQqd As QueryDef
CTQsql = CTQsql & "TRANSFORM Avg(Data.RNumeric) AS
AvgOfRNumeric "
CTQsql = CTQsql & "SELECT Data.MLO "
CTQsql = CTQsql & "FROM Data "
CTQsql = CTQsql & "WHERE (" & strWhere & ") GROUP BY Data.MLO "
CTQsql = CTQsql & "PIVOT " & "[Properties.Abbreviation]" & "&"
&
"[TestMethods.Abbreviation]"
Set CTQqd = CurrentDb.QueryDefs("qryCT")
CTQqd.sql = CTQsql
DoCmd.OpenQuery ("qryCT")
Debug.Print CTQsql
'Assign results of crosstab to text boxes in report.
Dim CHqd As QueryDef
Set CHqd = CurrentDb.QueryDefs("qryColumnHead")
CHqd.sql = CHsql
CHqd.Close
DoCmd.OpenQuery ("qryColumnHead")
DoCmd.OpenReport "rptDataCrossTab", acViewPreview
End If
ErrExit:
Exit Sub
ErrHandle:
MsgBox Err.Description
Resume ErrExit
Resume
End Sub
Allen Browne said:
Marcie, what you are seeking to do is possible, but not simple. It will
require quite a bit of coding. Typically, I use a report rather than a
form
for this (since resutls are read-only anyway and it prints better.)
In essence, you decide on the maximum number of columns your form will
cope
with, and place an unbound text box on the form for each one. Name them
txt1, txt2, txt3, etc. (so you can refer to them in a loop.) And save the
form without any RecordSource.
In its Open event, you build up a string that is the SQL statement that
gives you a record for each column heading (i.e. each combination of
[Property] + [TestMethod] that maches the criteria for this run.)
OpenRecordset. Loop through the records, assigning the ControlSource of
each
text box to the right 'field' that will be generated this run. If you
have
too many, give a warning that your form doesn't cope; if you have more
than
enough, hide the remaining ones and set the Left and Width of the
existing
ones to take advantage of available space. Simultaneously, build the IN
list
for the PIVOT clause you will need for your crosstab.
Now you have the form set up, close the recordset, and build the crosstab
query string. You can probably use the same WHERE clause you used above.
Include the column heading names string in the PIVOT clause (just in case
any more or fewer columns turn up/disappear [which could happen in a
multi-user scenario.]) Assign this crosstab query string to the
RecordSource
of the form.
It's not the simplest thing in the world, but is feasible if you have a
good
knowledge of SQL, VBA, and recordsets.
--
Allen Browne - Microsoft MVP. Perth, Western Australia
Reply to group, rather than allenbrowne at mvps dot org.
I have made several filter forms based Allen Browne's example. Thanks
Allen!! I would like to make a filter form that filters the rows and
headers
for a crosstab query and displays the sorted records in the bottom of
the
form. I don't want my users to need to learn how to make a crosstab
query.
They won't use it if they have to learn too much. I have a data table
which
contains MLO (cataloge number, text field), Property (ie boiling pont),
TestMethod, NResults (number field), TResults (text field), and units.
I
want MLO to be the row heading. I used a query to make the column
headings
based on abreviations for property and test method since you can only
have
one column heading field in a crosstab. There are also proptery, test
method, and units tables that are used as look up tables. The property
and
test method tables are joined through a junction table (many to many).
Conditions of the tests are contained in a conditions table that is
related
to the data table through a junction table (many to many). My form has
multiselect list filter boxes for MLO, Property, Method, Tresults and
Nresults. Is this possible to do this on one form or do I need to make
the
form open a query based on search criteria? Thanks.
Marcie