this one is the screenshot on the visual basic report. as you can see it starts at august then december then february but it i already group by it on the access which is this.
this is a query in the access im not sure if i did the right thing but i is already ordered by the earliest .
here is the sql code from the ms access
SELECT MonthName(Month([Date_sold])) & ' ' & Year([Date_sold]) AS Month_Sold, Sum(tblSell.Total_Price) AS Total_Earnings, Sum(tblSell.Quantity_Bought) AS Total_Medicine_Sold, tblSell.Generic_name, tblSell.Brand_Name
FROM tblSell
GROUP BY MonthName(Month([Date_sold])) & ' ' & Year([Date_sold]), tblSell.Generic_name, tblSell.Brand_Name, Year([Date_sold]), Month([Date_sold])
ORDER BY Year([Date_sold]), Month([Date_sold]);
in short is it doesnt order by on my report on the visual basic it should show february first like the one on ms access but it shows august which is different.
Order by, I believe, gets over written by the reports Order By property in the Data tab, on the property sheet. Either set it there or make sure it is empty. Then set the reports properties like this:
Me.OrderBy = "[SomeField], [AnotherField]"
Me.OrderByOn = True
EDIT:
All Microsoft products allow developers access to a development environment using a language called VBA (Visual Basic for Applications). You can use this language to write programs and macros to enhance products. Take a look here, although it's a bit old it may still be relevant: http://visualbasic.about.com/od/learnvba/l/aa030803b.htm
For you, you will need to add the code I suggested to the OnLoad event of the report. To do this:
Open Access.
Open your report in Design View.
On the left hand side, you should see a tab called Property Sheet
Select the Event Tab
in the OnLoad event, click the "..." (ellipsis) button
This will bring up the VBA code.
Add This:
Private Sub Report_Load()
Me.OrderBy = "[SomeField], [AnotherField]"
Me.OrderByOn = True
End Sub
Try that and see if it works.
The reason why is it not sorting (I am having this same problem at work doing some shipment order reports) is because the code is not reading the date. It will list them aplhabetically because it is a text field and not a short date. I just went to the parameters and was able to fix it there.
Related
Driving me bonkers...
The problem is one of speed.
I have a working SQL Server linked to a client accessible website, which I am wanting to add an Access front end to enable us office bound staff to better support both client and field staff.
The current form I have constructed is a main form with five sub forms contained within it, giving us all the relevant client information in one view. This works however is taking 24 seconds to load a single clients complete records.
I have looked at the SQL Server and found the absence of indexes, fixed this and got the time down to 24 seconds with consequent loads closer to 18 seconds depending on the client (some have a lot more records). This might be okay, as whilst this is a relative eternity in computing time in real world time its okay...but not great. I would like to see if I can get a better load by changing the way I connect and how the form is bound to the records etc.
In looking at the various ideas and reading a lot I found:
https://learn.microsoft.com/en-us/office/vba/access/concepts/activex-data-objects/bind-a-form-to-an-ado-recordset?source=docs
Which appealed to me as I am more inclined to use ADO, seldom if ever to I use DAO. ADO I understood originally was intended to use with SQL and so on, and it seems like a sensible idea.
Again as I understand it if I can get this to work it will act as a pass through query returning only one record over the net and should consequently speed my form up considerably. However it wont work.
My code is:
Private Sub cssSetForm(lngID As Long)
Dim cnn As New ADODB.Connection
Dim Rs1 As New ADODB.Recordset
Dim strSQL As String
Dim strR As String
cnn = "Provider=MSOLEDBSQL;Server=Server;Database=DatabaseName;UID=UserName; PWD=Password;"
cnn.Open
strSQL = "SELECT Clients.Clientid, Clients.AccountContact, Clients.AccountEmail, Clients.Address, Clients.Name, Clients.OfficePhone, Clients.PostCode, " & _
"Clients.ShentonAcc, Clients.Suburb FROM Clients WHERE (((Clients.Clientid)=" & lngID & "));"
With Rs1
Set .ActiveConnection = cnn
.Source = strSQL
.LockType = adLockPessimistic
.CursorType = adOpenKeyset
.Open
End With
Debug.Print Rs1.RecordCount
Me.Recordset = Rs1
End sub
Now I am getting no errors until Me.Recordset=rs1 which is generating an error 3251 Operation is not supported for this type of object which is very nice for someone that understands why this is not supported when it is no different than I can see to the example I was copying from.
I don't understand why the form I am working on doesn't support recordsets according to the error message? Is there an error in my code? Is the error in my understanding of the destructions from the linked site? Is the error something else?
Thanks for the help
Well, loading up 5 sub forms is a lot of data pulling. converting to ado reocdsets is NOT going to speed this up.
What you want to do here is NOT load up the sub forms until such time the user say clicks on the appropriate tab to load the one given sub form.
As long as the form in question is opened with a were clause, then the one main form will ONLY pull the one main record from sql server. So doing all kinds of fancy reocrdsets etc. will gain you next to nothing. So, always - but always launch your main form to the one record. If that main form is bound to a table of 5,000 rows, or 1 million rows, it will load instant despite the fact that the form is bound directly to the linked table with 1 million rows.
With this one main form, you edit or do whatever, and then close it. You are then of course right back to the search form/prompt you have to ask the user what reocrd to work on. So, how a accouting package works, or even google? You search, display the search resutlts and pick ONE thing to view. This approach should get your main form load down to about 1 second. Again, just use the "where" clause when you open that form:
eg:
dim strInv as string
strInv = InputBox("Enter invoice number to view")
docmd.OpenForm "frmInvoice",,,"InvoiceNum = " & strInv
Of course the above is air code, and you will likely build some search form say like this:
So in above, the user types in a bit of the name. We then fill the form with a simple where clause, or
me.MySubForm.RecordSource = "select * from tourCust where LastName like '" & sTextbox & "*'"
When a user clicks on the glasses icon to edit + view the ONE row, we use this:
docmd.OpenForm "frmDetails",,,"id = " & me!id
Again, all bound forms, and dispite the tables having 500,000+ rows, the loading of the forms is instant - even when the back end is SQL server.
So, adopt a prompt + search results + edit/view design pattern. EVERY single software system has this loop or design pattern. Not only is it user friendly, it also performs well since access DOES NOT pull the whole table, but ONLY the reocrds you tell the form to load by using the where clause as per above.
Now, for the child forms (sub forms).
As noted, don't load them until the user actually clicks on the given tab.
So, in the on-change event of the tab, you can go:
If Me.TabMainpage.Pages(Me.TabMainpage).Name = Me.pgeDocs.Name Then
'' the tab been changed to show past tours
dim strSQL as string
strSQL = "select * from tblPastTours where tour_ID = " & me!ID
me.
' dynamic load the sub form
If Me.frmSubPastTours .SourceObject = "" Then
Me.frmSubPastTours.SourceObject = "Forms.frmPastTours"
End If
' now load sql into form
me.frmSubPastTours.Form.RecordSource = strSQL
The above is mostly air code, but the idea here is:
don't load the sub form until you need to.
OR YOU can have the sub form load, but leave its RecordSource blank and STUFF in the sql you need for display WHEN you click on the tab.
It is possible that you need all sub forms to display. You could thus leave all sub form RecordSource blank, and then it the main form on-load event, simply stuff in the sql to each sub form. This might improve speed a bit, and with your slower connection this would be the least amount of work.
You "fail" to mention how you launch + load the main form, but as noted, it should be opend to the ONE reocrd. The link master/child pulling of data can be bit slow, and I can't say JUST using the above sql stuff into those forms will help a lot. I would try that first as it is the least amount of work. If load time is still too slow, then placing te sub forms behind a tab control and ONLY loading the sub form, and then setting the datasource will be the fastest.
Attempting to build all those recordsets, and then bind them to a form? It not speed things up, and just shoving a sql string into the form (or sub form) recordSource amounts to really the SAME thing and same performance anyway. So, you save tons of work and code, and quite much the above idea not only applies to sql server back ends, but we all VERY often dynamic load sub-forms and don't load them until such time you view the sub form say behind a tab control.
Hopefully not too difficult question but I cannot figure this out and have been unable to find anything searching the forums.
I want to convert the output of my toggle boxes from 1,2,3,4,5 to the text each button displays.
Couldn't find any setting on the toggle boxes properties themselves so decided I would have to write a macro/vba to do it from the table but as it's quite new to me I am struggling on syntax.
I have tried doing this on the inbuilt data macro mainly, but also tried it via a query and vba and still couldn't figure it out.
[don't have any reputation yet so have not been allowed to post pics of my macro attmept]
please help! Any solution using vba, data macro or a query would be great
EDIT
To be specific rather than a message box I want to update field1 in my table "Major Equipment" based off the option group selection this is my latest attempt but still not sure how to reference the option group. Do I need to set grp equal to the option group and if so how? Is it something like forms!myform!optiongroup ?
Option Compare Database
Function MyFunc(grp As OptionGroup)
Dim rcrdset As Recordset
set grp =
Set rcrdset = Application.CurrentDb.OpenRecordset("Major Equipment", dbOpenDynaset)
Select Case grp.Value
Case 1
With rcrdset
.AddNew
![Field1] = "Not Reviewed"
Case 2
.AddNew
![Field1] = "Reviewed"
Case Else
MsgBox "Error"
End Select
End Function
Also just realised since these toggle buttons will be updated by the user and so I probably need an update rather than addnew?
http://i59.tinypic.com/2ym8wet.jpg
Your buttons are part of an Option Group. That is what you must reference. Below is a snippet from my net search.
From the AfterUpdate() event of your Option Group:
Call MyFunc(Me.MyGroup)
... which will use Select Case to evaluate:
Function MyFunc(grp As OptionGroup)
Select case grp.Value
Case 1
MsgBox "Option value is 1."
Case 2
MsgBox "Option value is 2."
Case Else
MsgBox "Huh?"
End Select
End Function
If you are entirely new to VBA, there are a half-dozen things to learn here, but they will serve you well. VBA provides a bit less-friendly-looking start than a macro, but I can tell you have more adventures ahead and I suggest you skip macros. For most needs, VBA will serve you better; and it's much easier to trouble shoot or provide details when you need advice.
To convert this to a useful function, you will fill a string variable rather than raising a message box. Then you can use the string variable to do something like run an update query. Your latest edit suggests you will go for something like:
strSQL = "UPDATE [Major Equipment] " _
& "SET Field1='" & strUserSelection & "' " _
& "WHERE MyID=" & lngThisRecord
DoCmd.RunSQL strSQL
Your last edit proposes using a DAO recordset. I think you might be fine with the humble DoCmd. Less to learn. You can hammer out a prototype of the query in good ol' Access; then switch to SQL View and paste the query into your VBA module. Insert variables as seen above, taking care with the quote marks. If it doesn't work, use Debug.Print to grab the value for strSQL and take that back to good ol' Access where you can poke at it into shape; use your findings to improve the VBA.
MS Access randomly deletes a SQL query's content when a non-vba macro exports the query contents to excel. The initial export works and the data is exported to Excel correctly, but then (about 50% of the time...) the SQL underlying the query goes missing. This is definitely triggered by the export (one can do a before and after comparison of the query).
The following site references the problem and talks about a VBA solution that automaticaly rebuilds the SQL query. I'd much prefer to just prevent this from happening rather than fixing it post-mortem. This forum post on bytes.com also discusses the issue. The suggested solution is not relevant.
The problem database was originally designed in Access 2007 and is now being used in Access 2010. All the queries and macros that are involved in this issue were created using Access 2007. These components were stable in Access 2007. This leads me to believe that the problem is not contained within the SQL. All the SQL queries are simple SELECT statements, there are no inserts, drop or make table commands.
I've just encountered this bug myself. None of the solutions posted here worked/were applicable to my case, and I wasn't 100% happy with the work-arounds offered, particularly the geeksengine.com one, which requires that you delete the Query entirely and re-create it from code that you've stored in VBA - not a very generalisable solution, and if someone else has to maintain your database, they'll find themselves perplexed to discover that the Query they changed occasionally reverts itself to its old code, seemingly at random.
So I took a different approach, and wrote a generic routine that stores the SQL code of a Query before exporting the Spreadsheet, and then restores the code immediately afterwards if it's been erased:
Sub SafeSendQuery(QueryName As String, FileType As Variant, EmailAddresses As String, SubjectLine As String, BodyText As String)
Dim QueryCode As String
'Access has a bug where it sometimes erases the SQL code of the Query it's sending as a spreadsheet
'This stores the code in a string, so that we can restore it if it's been erased
QueryCode = CurrentDb.QueryDefs(QueryName).SQL
DoCmd.SendObject ObjectType:=acSendQuery, ObjectName:=QueryName, OutputFormat:=FileType, To:=EmailAddresses, Subject:=SubjectLine, MessageText:=BodyText, EditMessage:=True
'If the SQL code was erased, restore it
If CurrentDb.QueryDefs(QueryName).SQL <> QueryCode Then
Debug.Print "SQL Code Missing, restoring it now."
CurrentDb.QueryDefs(QueryName).SQL = QueryCode
End If
End Sub
Note that I wrote this for DoCmd.SendObject, as my users need to email the spreadsheet, but it should work just as well for DoCmd.OutputTo - just replace the DoCmd.SendObject line with a DoCmd.OutputTo one, and modify the parameters as necessary.
This is what a subroutine that calls it looks like:
Sub EmailAQuery()
Dim QueryName As String
Dim FileType As Variant
Dim EmailAddresses As String
Dim SubjectLine As String
Dim BodyText As String
QueryName = "Quarterly Figures"
FileType = acFormatXLSX
EmailAddresses = "bob#company.com; Sally#company.com"
SubjectLine = "Quarterly Figures for " & Format(Date, "mmmm yyyy")
BodyText = "Please see the Quarterly figures data for " & Format(Date, "mmmm yyyy") & ", attached."
Call SafeSendQuery(QueryName, FileType, EmailAddresses, SubjectLine, BodyText)
End Sub
Did you try using the expression builder to represent the query in access language?
Double click 'criteria' in the query design window, and build the expression.
For example:
SELECT table1.field1
FROM table1 INNER JOIN table2 on table1.field1 LIKE table2.field1
This query would become cleared, even though it worked. Use the expression builder to build the "LIKE" expression. It should look like this:
SELECT table1.field1
FROM table1 INNER JOIN table2 on table1.field1 = table2.field1
WHERE ((([table1]![field1] LIKE [table2]![field1])));
I resolved the issue by modifying the query. Initially the query was joining three tables through both inner and outer joins. I simplified the query into just one join by using an intermediate table, after which Access ceases to delete the query after it runs the macro. This is definitely a bug, one where Access chokes when its macro is tasked to run a query with complex joins.
I experienced the same issue in Access 2010. I was able to resolve it by using an OpenQuery action before the ExportWithFormatting action and a CloseWindow – Query action after the ExportWithFormatting action in my macro. In this way, the query would open, then export, and then close all within the same macro. I also used a StopMacro action at the very end.
I had this problem in Access 2010.
For me this was caused by a bug that only occurs if I collected these queries in a group.
Once I removed them from the custom group and left them as unassigned objects, the queries remained intact.
I've been charged with refactoring and extending the functionality of an big Access database. The existing VBA code is pretty bad, so I'd like to clean it up by removing uneccessary functions and simplifying the rest. I wonder how I can find all usages of the functions?
As for the VBA project itself, I can of course search for their names. As for the SQL queries: I've written a function which prints all queries to the VBE's intermediate window, so I can search them as well.
But many functions are also used in forms and reports. Is there a way to find them all? There are a lot of complex forms/reports, so simply having a look at one control after the another or removing the function and testing if everything still works is not feasible at all.
Unfortunately, there's no search function (that I know of) in Access which includes form and report properties.
However, there's an undocumented method SaveAsText that copies forms and reports into text files. If you extract all your forms and reports...
Dim db As Database
Dim d As Document
Set db = CurrentDb()
For Each d In db.Containers("Forms").Documents
Application.SaveAsText acForm, d.Name, "C:\export\" & d.Name & ".frm"
Next
For Each d In db.Containers("Reports").Documents
Application.SaveAsText acReport, d.Name, "C:\export\" & d.Name & ".rpt"
Next
...you can use "regular" text search tools (such as findstr, which is included in Windows) to find occurrences of certain words:
C:\export>findstr /I "\<myFunction\>" *
Form1.frm: OnClick ="=myFunction()"
I have a Word template (suggestion from) which includes an autonew macro to insert a reference number at a book mark and an action button (Submit)which saves the resulting document with the reference number as part of the file name and closes Word. This works perfectly well when opening the template via Windows Explorer.
We also have a PowerPoint show with action settings hyperlinking to various documents. The link will open the above template OK but does not insert the reference number. Also when the 'submit' button is hit, the file saves as another template with the reference number included.
I am not sure if the issue is Word or PowerPoint-related. The code for the Word template is
Sub AutoNew()
REF = System.PrivateProfileString("L:\Local\Lab\Section - Support Services\Health and Safety\H&S Suggestions\Settings.Txt", _
"MacroSettings", "REF")
If REF = "" Then
REF = 1
Else
REF = REF + 1
End If
System.PrivateProfileString("L:\Local\Lab\Section - Support Services\Health and Safety\H&S Suggestions\Settings.Txt", "MacroSettings", _
"REF") = REF
ActiveDocument.Bookmarks("REF").Range.InsertBefore Format(REF, "000#")
End Sub
Private Sub CommandButton1_Click()
REF = System.PrivateProfileString("L:\Local\Lab\Section - Support Services\Health and Safety\H&S Suggestions\Settings.Txt", _
"MacroSettings", "REF")
ActiveDocument.SaveAs FileName:="L:\Local\Lab\Section - Support Services\Health and Safety\H&S Suggestions\Suggestion " & Format(REF, "000#.doc")
Application.Quit
End Sub
Any help or pointers would be appreciated as if it works I'd like to use for various other templates.
From the description, it's kind of hard to get an accurate idea of what's happening, but it SOUNDS like the the AUTONEW just might not get run in that particular combination.
You could verify this by using some logging or MSGBOX calls to see exactly what macros are being run, when.
Check the docs on Autonew here
http://support.microsoft.com/kb/211659
Sounds like it won't run if the macro is saved in Normal, which doesn't sound like the case here but it's worth noting.
You might also consider using the AutoOpen macro and checking other elements to make sure this is a brand new doc instead of one that's already been saved (like checking the content of the Document.Fullname property).