![]() | |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
In another postibg I was querying the speed of DLookup, and was told that the performance was good. |
#3
| |||
| |||
|
#4
| |||
| |||
|
|
Have you tried doing this in two stages? I think Rick is on the right track here. I had a similar requirement recently and broke the solution into two parts, first was the SELECT DISTINCT that grabbed all the 'raw' data I required, then I crosstabbed that to provide the layout I wanted. Using joins across the tables is much faster than a DLookup (which I tried first). My query time went from 20mins to six seconds across 500K rows - a huge improvement. Give it a try :-) The Frog |
#5
| |||
| |||
|
|
On 24/09/2010 09:11:57, The Frog wrote: Have you tried doing this in two stages? I think Rick is on the right track here. I had a similar requirement recently and broke the solution into two parts, first was the SELECT DISTINCT that grabbed all the 'raw' data I required, then I crosstabbed that to provide the layout I wanted. Using joins across the tables is much faster than a DLookup (which I tried first). My query time went from 20mins to six seconds across 500K rows - a huge improvement. Give it a try :-) The Frog Thanks for coming back. The CrossTab solution works to get the individual names, currently giving me 9 columns of individual names (Maximum no of people living in 1 house). As I said, most of these names will occur numerous times (same family living in the same house) I then need to reduce this normally to just 1 surname, but in the CrossTab which gives some 500 rows there are about 30 rows with 2 names and 2 rows with 3 names. Again using built in functions like IIf() and Instg(), I can extract names from the first 5 columns, but then I run into "Query too complex" problems if I try to check all 9 columns. My CrossTab produces 9 columns of individual surnames and a combined column of all the surnames separated by a # space Result Result wanted Blackburn# Blackburn# Blackburn# Blackburn# Blackburn# Blackburn Brooke# Brooke# Brooke# Edwards# Brooke# Brooke# Brooke & Edwards Jefferies# Priestley# Jeffries & Priestley Tierney-Garneys# Garneys# Tierney-Garneys & Garneys (Need to check length as well as Instr() Smith# Smith Mason# Mason# Sale# Sale# Mason & Sale Douglas# Allott# Douglas# Douglas# Douglas & Allott King# Hodges# Harvey# Harvey# King, Hodges & Harvey Again I stress I seem to be limited to inbuilt functions to avoid problems with mail merge. Phil |
#6
| |||
| |||
|
|
Again I stress I seem to be limited to inbuilt functions to avoid problems with mail merge. Phil A function would be far easier to debug than massive IIFs() But a function is not available to external apps ...such as mail merge |
#7
| |||
| |||
|
|
Salad wrote: Again I stress I seem to be limited to inbuilt functions to avoid problems with mail merge. Phil A function would be far easier to debug than massive IIFs() But a function is not available to external apps ...such as mail merge |
#8
| |||
| |||
|
#9
| |||
| |||
|
|
On 24/09/2010 16:47:42, Salad wrote: Am already using a temp table to get over the problem, using inbuilt functions, but the risk is it's out of date. The solution I am hoping for is to use queries. The main Crosstab query gets the number of columns from the maximum number of people living at one address, but the design only changes if the maximum number of people living at one address changes. This is a rare occurrance, likely to happen once a year if a large family either join or leave the club. The other queries depending on the CrossTab query are built on the fly because I need to join 1 member table to each of the columns in the Crosstab. This code creates the first query "bbb" Member table is given an alias such as Mem_0, .... Mem_8 Function CreateQueryNew(StrQName As String, NoAtAddress As Integer) As Integer '?CreateQueryNew("bbb",9) ' ' Creates a query linking CrossTab query "XAllNames" to the correct number of Member Tables ' and names the Mem_0, Mem_1...... Mem_8 etc Dim MyDb As Database Dim MyQdf As QueryDef Dim SQLStg As String Dim i As Integer On Error GoTo CreateQueryNew_Err SQLStg = "SELECT XAllNames.*, " For i = 0 To NoAtAddress - 1 SQLStg SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemSurName, Mem_" & CStr(i) & ".MemFirstName, " SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemTitle, Mem_" & CStr(i) & ".MemTitleOption, " SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemPhone, Mem_" & CStr(i) & ".MemEMail, " SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemMobile, Mem_" & CStr(i) & ".MemHeadOfHouseID, " Next i SQLStg LStg = Left$(SQLStg, Len(SQLStg) - 2) & " " ' Remove last comma and add space SQLStg = SQLStg & "FROM " For i = 1 To NoAtAddress - 1 SQLStg = SQLStg & "(" Next i SQLStg = SQLStg & "XAllNames " For i = 0 To NoAtAddress - 1 SQLStg = SQLStg & "LEFT JOIN Member AS Mem_" & CStr(i) SQLStg SQLStg = SQLStg & " ON XAllNames.[" & CStr(i + 1) & "] = Mem_" & CStr(i) & ".MemberID) " Next i SQLStg LStg = Left(SQLStg, Len(SQLStg) - 2) & ";" ' Remove last bracket & add ; With CurrentDb For Each MyQdf In .QueryDefs If MyQdf.Name = StrQName Then ' Does Query exist .QueryDefs.Delete (StrQName) ' Yes, delete it Exit For End If Next Set Set MyQdf = .CreateQueryDef(StrQName, SQLStg) ' CreateQueryNewdef command line follows .QueryDefs.Refresh Set MyQdf = Nothing .Close End With DoCmd.SelectObject acQuery, StrQName, True CreateQueryNew = NoAtAddress Exit Function CreateQueryNew_Err: MsgBox Err.Description End Function End result is to be able to do mail merge letter with a choice of formal names such as Mr. & Mrs. J. Smith Mr. & Mrs. John Smith Mr. J. Smith & Mrs. M Smith Mr. J. Smith & Mrs. M Jones Mr. J. Smith & family ' If there are a lot of them and Dear John & Mary ' that bit is OK Phil |
#10
| |||
| |||
|
|
Phil wrote: On 24/09/2010 16:47:42, Salad wrote: Am already using a temp table to get over the problem, using inbuilt functions, but the risk is it's out of date. The solution I am hoping for is to use queries. The main Crosstab query gets the number of columns from the maximum number of people living at one address, but the design only changes if the maximum number of people living at one address changes. This is a rare occurrance, likely to happen once a year if a large family either join or leave the club. The other queries depending on the CrossTab query are built on the fly because I need to join 1 member table to each of the columns in the Crosstab. This code creates the first query "bbb" Member table is given an alias such as Mem_0, .... Mem_8 Function CreateQueryNew(StrQName As String, NoAtAddress As Integer) As Integer '?CreateQueryNew("bbb",9) ' ' Creates a query linking CrossTab query "XAllNames" to the correct number of Member Tables ' and names the Mem_0, Mem_1...... Mem_8 etc Dim MyDb As Database Dim MyQdf As QueryDef Dim SQLStg As String Dim i As Integer On Error GoTo CreateQueryNew_Err SQLStg = "SELECT XAllNames.*, " For i = 0 To NoAtAddress - 1 SQLStg SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemSurName, Mem_" & CStr(i) & ".MemFirstName, " SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemTitle, Mem_" & CStr(i) & ".MemTitleOption, " SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemPhone, Mem_" & CStr(i) & ".MemEMail, " SQLStg = SQLStg & "Mem_" & CStr(i) & ".MemMobile, Mem_" & CStr(i) & ".MemHeadOfHouseID, " Next i SQLStg LStg = Left$(SQLStg, Len(SQLStg) - 2) & " " ' Remove last comma and add space SQLStg = SQLStg & "FROM " For i = 1 To NoAtAddress - 1 SQLStg = SQLStg & "(" Next i SQLStg = SQLStg & "XAllNames " For i = 0 To NoAtAddress - 1 SQLStg = SQLStg & "LEFT JOIN Member AS Mem_" & CStr(i) SQLStg SQLStg = SQLStg & " ON XAllNames.[" & CStr(i + 1) & "] = Mem_" & CStr(i) & ".MemberID) " Next i SQLStg LStg = Left(SQLStg, Len(SQLStg) - 2) & ";" ' Remove last bracket & add ; With CurrentDb For Each MyQdf In .QueryDefs If MyQdf.Name = StrQName Then ' Does Query exist .QueryDefs.Delete (StrQName) ' Yes, delete it Exit For End If Next Set Set MyQdf = .CreateQueryDef(StrQName, SQLStg) ' CreateQueryNewdef command line follows .QueryDefs.Refresh Set MyQdf = Nothing .Close End With DoCmd.SelectObject acQuery, StrQName, True CreateQueryNew = NoAtAddress Exit Function CreateQueryNew_Err: MsgBox Err.Description End Function End result is to be able to do mail merge letter with a choice of formal names such as Mr. & Mrs. J. Smith Mr. & Mrs. John Smith Mr. J. Smith & Mrs. M Smith Mr. J. Smith & Mrs. M Jones Mr. J. Smith & family ' If there are a lot of them and Dear John & Mary ' that bit is OK Phil Sub Qtest() Dim r As Recordset Dim i As Integer Set r = CurrentDb.OpenRecordset("YourQueryName", dbOpenSnapshot) If r.RecordCount > 0 Then r.MoveLast r.MoveFirst Do While Not r.EOF() 'get number of records and fields. MsgBox "There are " & r.RecordCount & " records and " & _ r.Fields.Count & " fields." For i = 0 To r.Fields.Count - 1 MsgBox r.Fields(i).Name & " " & r.Fields(i).Value Next 'could process names here and insert into a table. r.MoveNext Loop End If r.Close Set r = Nothing End Sub Is the mailmerge being called from Word or Access? If Access, I think you could run some code to process the records then call something like Albert Kallal's mailmerge routine to finish the job up. |
![]() |
| Thread Tools | |
| Display Modes | |
| |