Open new instance of a form based on data in field of first form - ms-access-2007

I have a data entry form where the data clerk enters client ID among other things. Client ID's are unique to each client. I am currently trapping for duplicate ID's and allowing the clerk to go to the search form and seach for the duplicate ID to verify that it is indeed the same person and not an error inputting data. I would rather open a new instance of the data entry form based on the client ID inputted into the data entry form. I can open a new instance but am not sure how to make it display the client data based on the client ID.

There is no good way to do this except to just turn off the screen painting. Here's some code from one of my apps:
Dim frm As Form_frmInventory
Dim strRecordsource As String
Dim intType As Integer
DoCmd.Hourglass True
Application.Echo False
Set frm = New Form_frmInventory
frm!boxHeader.BackColor = 3276900 ' 5483007
frm!boxFooter.BackColor = 3276900 ' 5483007
strRecordsource = "SELECT qryInventoryForm.*, varZLStoNull(IIf([tblInventory].[InventoryClass] In ('BKS','FAC','MTH','MUS','REF','SSC'),[Creator] & [Dates] & OtherAuthors([OtherAuthors]))) AS BibCreator, CreatorDates([Birth],[Death],[OtherAuthors]) AS Dates, varZLStoNull(Trim(nz(UCase([tblBib_Authors].[LastName]) & IIf(Not IsNull([tblBib_Authors].[FirstName]),', ') & [tblBib_Authors].[FirstName],'Anon.'))) AS Creator, tblBib_Authors.CreatorCategories, Nz([CreatorSort],[LastName] & [FirstName]) AS NameSort FROM qryInventoryForm LEFT JOIN tblBib_Authors ON qryInventoryForm.CreatorID = tblBib_Authors.CreatorID WHERE ([quantity]>0 Like getSold()) AND (qryInventoryForm.InventoryID=" & lngInventoryID & ") ORDER BY Nz([CreatorSort],[LastName] & [FirstName]), InventoryClass, ShortTitle;"
frm.RecordSource = strRecordsource
' need to change the caption and disable certain things
frm.Caption = frm.Caption & " -- " & frm!InventoryClass & "-" & Nz(frm!InventoryNo, Format(frm!InventoryID, "00000"))
frm!fldShortTitle.SetFocus
frm!cmbClassFind.Enabled = False
frm!cmbCreatorFind.Enabled = False
frm!cmbInventoryNumber.Enabled = False
[etc.]
frm.Visible = True
GoTo exitRoutine
CloseForm:
Call CloseForm(Me, True)
exitRoutine:
Application.Echo True
DoCmd.Hourglass False
Exit Sub
The CloseForm() sub is pretty important, as you have to keep track of multiple instances of the form and close the right one. I got the code from the ADH97 and adapted it from there (just the basics).
It would appear from that code (I've forgotten the details) that a form instantiated with Set frm = New Form_frmInventory is not visible until you explicitly reveal it. That's a plus, as it should mean that you don't have to turn off the screen (i.e., Application.Echo False), but I'm pretty sure that I recall needing it anyway to make things appear smoothly. My memory is that the form would appear with its normal colors and then the background colors would change visibly as the code ran. This means it was visible, so I'm not sure why it's necessary to then explicitly set the form visible.
Anyway, that should get you started, I think!

Related

MS Access: Bound condition in endless Form via vba,

I just try to create a calendar in MS-Access out of 42 unbound Forms, using them as endless Listes of entrys.
Now I like to fill them with entrys of different typ (group-appointments, entrys from Joe or from Marry etc.) with a recordset, createt for every of this 42 forms. And in the end, all this entry shall have a specific color, so Joe will get his in blue and Marry some in red.
So first I fill the recordset of the Form and than I run threw it like this:
Dim objFormatConditionGroup As FormatCondition
Dim objFormatConditionJoe As FormatCondition
Dim objFormatConditionMarry As FormatCondition
Dim ctl As Control
With Me
Do While Not .Recordset.EOF
Set ctl = .Topic
Set objFormatConditionGroup = ctl.FormatConditions.Add(acExpression, , "'" & .Recordset.typ & "' = '1'")
objFormatConditionGroup.BackColor = enmColor.Red
objFormatConditionGroup.ForeColor = enmColor.White
Set objFormatConditionJoe = ctl.FormatConditions.Add(acExpression, , "'" & .Recordset.typ & "' = '2'")
objFormatConditionJoe.BackColor = enmColor.Blue
objFormatConditionJoe.ForeColor = enmColor.White
Set objFormatConditionMarry = ctl.FormatConditions.Add(acExpression, , "'" & .Recordset.typ & "' = '3")
objFormatConditionMarry.BackColor = enmColor.White
objFormatConditionMarry.ForeColor = enmColor.Black
.Recordset.MoveNext
Loop
End with
Works somehow, but if I have multiple entry in one List, I always get the style of the last used block in for all entrys. Like: If there is a Groupappointment an something from Marry in one day (entrys are sortet by recordset.Typ), all entrys appear in Marry-Styl.
I gues, there is something wrong in the conditions-part of FormatConditions, but I can not figure it out. It shout be a String, "1=1" and "0=1" work like expectet. But how can I refere to the recordset of only one entry in the List?
Or how can I change the control .Topic of just one entry in the List and not all of them in the same step?
In FormatConditions, you can't refer to VBA variables or values. You need to refer to the actual column from the form recordsource.
E.g.
ctl.FormatConditions.Add(acExpression, , "[Typ] = '1'")
And don't do this in a recordset loop. Add each FormatCondition once. (As you have, but without the loop.)

Passing Parameter to Crystal Reports XI from Visual Studio 2015

I am running into problems with the passing of parameters to an externally created Crystal Reports XI report from the WinForms application I'm building in Visual Studio 2015 Community Edition. No matter what I try to do, the report doesn't seem to get the value unless I manually select it at the prompt (which shouldn't even be popping up) when the report is being displayed. I'm using the same code I've used in a previous application (although that one was built in VS2008), but I've tried a number of "alternate" versions of the code in my attempts to get this working. Here's the code that I'm currently using:
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.Shared
Module modReports
Private WithEvents DocumentToPrint As New Printing.PrintDocument
Private Sub ShowReport(ByVal LID As Integer, ByVal InHouse As Boolean)
Dim Report As New ReportDocument
Dim ReportParameters As ParameterFieldDefinitions = Nothing
Dim Parameter As ParameterFieldDefinition = Nothing
Dim ApplicationValue As ParameterDiscreteValue = Nothing
Dim ReportValues As ParameterValues = Nothing
Dim ReportViewer As New frmReport
Dim Response As DialogResult = DialogResult.Cancel
PrintingReport = True
Report.Load(CRYSTAL_REPORT_FILE_PATH & "ExampleReport.rpt")
Report.Refresh()
Report.VerifyDatabase()
ReportParameters = Report.DataDefinition.ParameterFields
Parameter = ReportParameters.Item("PrintAll")
ReportValues = New ParameterValues
ApplicationValue = New ParameterDiscreteValue
'Parameter.CurrentValues.Clear()
'ReportValues.Clear()
ReportValues = Parameter.CurrentValues
If LID = 7777 Then
ApplicationValue.Value = True
Else
ApplicationValue.Value = False
End If
ReportValues.Add(ApplicationValue)
Parameter.ApplyCurrentValues(ReportValues)
Response = MessageBox.Show("Do you want to send this report directly to the printer?", "SEND TO PRINTER", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
If Response = DialogResult.No Then
With ReportViewer
.rptViewer.ReportSource = Nothing
.rptViewer.ReportSource = Report
.WindowState = FormWindowState.Maximized
.rptViewer.RefreshReport()
' Set zoom level: 1 = Page Width, 2 = Whole Page, 25-100 = zoom %
.rptViewer.Zoom(1)
.rptViewer.Show()
.ShowDialog()
End With
ElseIf Response = DialogResult.Yes Then
Dim SelectPrinter As New PrintDialog
Dim PrinterSelected As DialogResult = DialogResult.Cancel
With SelectPrinter
.Document = DocumentToPrint
.AllowPrintToFile = False
.AllowSelection = False
.AllowCurrentPage = False
.AllowSomePages = False
.PrintToFile = False
End With
PrinterSelected = SelectPrinter.ShowDialog
If PrinterSelected = DialogResult.OK Then
Dim Copies As Integer = DocumentToPrint.PrinterSettings.Copies
Dim PrinterName As String = DocumentToPrint.PrinterSettings.PrinterName
Dim LastPageNumber As Integer = 1
Dim PrintBuffer As String = String.Empty
LastPageNumber = Report.FormatEngine.GetLastPageNumber(New ReportPageRequestContext)
Report.PrintOptions.PrinterName = PrinterName
Report.PrintOptions.PrinterDuplex = DocumentToPrint.PrinterSettings.Duplex
Report.PrintToPrinter(Copies, True, 1, LastPageNumber)
If Copies = 1 Then
PrintBuffer = "Printed " & Copies & " copy of "
Else
PrintBuffer = "Printed " & Copies & " copies of "
End If
If LastPageNumber = 1 Then
PrintBuffer += LastPageNumber.ToString & " page."
Else
PrintBuffer += LastPageNumber.ToString & " pages."
End If
MessageBox.Show("The report was sent to the following printer:" & vbCrLf & " • " & PrinterName & vbCrLf & PrintBuffer, "REPORT PRINTED", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
PrintingReport = False
End Sub
End Module
The report itself is built to use an XML file as the data source, which is dynamically created by this application. All of that works normally, and oddly enough, if I send the report directly to the printer, it seems to print correctly without prompting me. It's only a problem when I try to display the report through the CrystalReportViewer object.
Some of the things I've tried without success:
I've tried with and without calling the Clear() methods on the
Parameter.CurrentValues and ReportValues objects.
I've tried moving all of the parameter setting logic to after I set the
ReportSource of the CrystalReportViewer control (rptViewer.ReportSource)
I've tried using alternate Crystal Reports objects (ParameterFields instead of ParameterFieldDefinitions and ParameterField instead of ParameterFieldDefinition).
I've tried removing all of the "complicated" code and just using the SetParameterValue method (i.e., Report.SetParameterValue("PrintAll", True)
I've even tried creating different types of parameter fields in the report itself (String, Boolean, Number) and passing appropriate values for those datatypes.
If I walk through the code, it doesn't appear to error out anywhere, and everything looks like it's working just great until I get to the .rptViewer.RefreshReport() line in the With ReportViewer block. I've verified that all of the parameters and values have only the value I am "selecting" via the application by checking them every step up to that point, and it all looks exactly as I expect it to look.
But the application (via Crystal Reports) continues to prompt me for the value I just passed in the code. If I select the value in that prompt, the report does generate correctly based on the value I select, but no matter what I "pass" in the programming, the prompt always defaults to True.
Does anyone have any suggestions that I may have overlooked for how to get this parameter to correctly pass to the CrystalReportViewer control? Please let me know if you need any additional information or have any questions about what I've set up so far here. Thank you in advance.
Okay, so based on the information I found over on http://www.it-sideways.com/2011/10/how-to-disable-parameter-prompt-for.html, it seems that the RefreshReport method for the CrystalReportViewer control basically wipes out any parameters and/or log on information:
1. ) Do not invoke CrystalReportViewer.RefreshReport Method
This method will refresh the data for the report currently displayed
in the CrystalReportViewer control. The report will prompt for
parameters or logon info is necessary.
So, this method is not needed unless the same
CrystalDecisions.CrystalReports.Engine.ReportDocument object is
reused.
By commenting out that line of the code, I was able to prevent the parameter prompt from being displayed. The only issue I have after making that change is that, even though the zoom level is being set to 1 (page width), and when I run the project the CrystalReportViewer control even shows that it's correctly set in the status bar ('Zoom Factor: Page Width' is displayed), the report itself is not actually zoomed in to the page width.
With the RefreshReport method uncommented, if I manually provided the value for my parameter, it would display the report properly zoomed. If I add the zoom button to the control (.rptViewer.ShowZoomButton = True), I can manually choose the Page Width option, which then correctly "re-zooms" the report to the desired level, but it won't immediately display that way if the RefreshReport method is not called.
Regardless, I can spend some time trying to fight that now, but I finally have it properly setting, passing and displaying the results of my parameter. I hope this helps someone else running into this issue.

VB.NET - Combobox goes blank when a button is clicked, databind doesn't update

Please forgive me, it has been some time since I've used VB.Net so this may be easy.
I have a simple login form with a text box, combobox and a button. The combobox is binded to a SQL database and displays the user names from Users table. The idea is that you select a name, type in a password, and you logon to a new form (This part works Great!). If you type a wrong password, the form pops up a message that says "invalid." For some reason at this stage, the combobox goes blank. The drop down now has empty spaces where names once were. Typing in a name with a password here results in object reference errors. I have tried everything to get the combo box to reset and searched the web but nothing works!!!
(I know this is not a secure login, this is just an easy example of binding data to a combo box and checking it against SQL table). Thanks for your help!
enter code here
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles BTN_Logon.Click
Try
Dim STR_User As String = Users_nameComboBox.SelectedValue
Dim STR_Pwd As String = TB_Pwd.Text
STR_User = STR_User.Trim
'MessageBox.Show(STR_User & "|" & STR_Pwd)'Used to verify this stage works
Dim numRecords As Int16 = UsersTableAdapter.FillByLogin(Me.Login_testDataSet.users, STR_User, STR_Pwd)
'MessageBox.Show(numRecords) 'Used to verify this stage works
If (numRecords > 0) Then
Dim DB_User As String = Me.Login_testDataSet.users(0).users_name.Trim
Dim DB_Pwd As String = Me.Login_testDataSet.users(0).users_pwd.Trim
'MessageBox.Show(DB_User & "|" & DB_Pwd)'Used to verify this stage works
If DB_User.Equals(STR_User) And DB_Pwd.Equals(STR_Pwd) Then
'User is authenticated for application
'This section works (removed to cleanup code)
Else
MessageBox.Show("ERROR" & STR_User & "|" & STR_Pwd) 'Shows that this stage works
'Need to figure out why combobox doesn't refill, using restart for now
'Application.Restart()
End If
End If
MessageBox.Show("ERROR" & STR_User & "|" & STR_Pwd) 'Shows that this stage works
'Need to figure out why combobox doesn't refill, using restart for now
'Application.Restart()
Catch ex As Exception
MessageBox.Show(ex.Message)
'Need to figure out why combobox doesn't refill, using restart for now
'Application.Restart()
End Try
End Sub
InitializeComponent
'Users_nameComboBox
Me.Users_nameComboBox.DataBindings.Add(New System.Windows.Forms.Binding("Text",
Me.UsersBindingSource, "users_name", True))
Me.Users_nameComboBox.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", Me.UsersBindingSource, "users_name", True))
Me.Users_nameComboBox.DataSource = Me.UsersBindingSource
Me.Users_nameComboBox.DisplayMember = "users_name"
Me.Users_nameComboBox.Name = "Users_nameComboBox"
Me.Users_nameComboBox.ValueMember = "users_name"

Can't Go To Specific Record on Continuous Form in MS Access

Searched and searched and cannot find a solution to this. I have a form with many continuous form subforms. When I change a value in, lets say FIELD_A on one of the subforms, I run calculations on several other subforms, then the focus returns to FIELD_A. However, during the calculations an update to the PARENT form happens, and needs to happen. So, when I return focus to the original subform, the first record on my subform has the focus. I need to then go to the record I was working on.
I've tried several options, but nothing works. However, if I set a DEBUG breakpoint at the line in the code where it moves to the specified record, then physically RUN the code from that line, it works! I've tried setting a wait period in there to no avail.
Here's a snippet of the code:
Call common.CalculateAllLoadTotals _
(Me, Me.AffiliateID, Me.ClientID, Me.FacilityID, Me.ProposalRevision)
Me.Recordset.FindFirst "[AffiliateID] = '" & Me.AffiliateID & "'" & _
" AND [ClientID] = " & Me.ClientID & _
" AND [FacilityID] = " & Me.FacilityID & _
" AND [ProposalRevision] = " & Me.ProposalRevision & _
" AND [EquipmentID] = " & currItemID
I also tried this:
dim currRecord as Long
currRecord = Me.CurrentRecord
' >>> REST OF CODE HERE <<<
Call common.CalculateAllLoadTotals _
(Me, Me.AffiliateID, Me.ClientID, Me.FacilityID, Me.ProposalRevision)
Me.Form.Recordset.Move = currRecord
As I said, the code works (either one) IF I pause it with a debug then continue executing. Strange.
Sorry that's will not be a complete answer but it is quite lot for a comment.
Regarding your first solution - I'd advise you to try Me.Recordset.Requery
to refresh current record in the main form without moving position.
Regarding you 2nd option - I'd advise to have a look at bookmarks - before update remember bookmark, make some calculations and then move position to the saved bookmark. Something like this -
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.FindFirst "[MyPK]=" & Me!cmbFindByPK
If Not rs.NoMatch Then
If Me.Dirty Then
Me.Dirty = False
End If
Me.Bookmark = rs.Bookmark
End If
Set rs = Nothing
taken from here Why clone an MS-Access recordset?
I suspect you are updating the recordset underlying the parent form. This causes the parent form to automatically requery, hence the subform position returning to the first record.
The solution is to update the controls on the parent form instead:
Me.Parent!Controlname = XXXX

VB.Net: How To Display Previous Shadow Copy Versions of File Allowing User to Choose One

I'm writing an Excel file recovery program with VB.Net that tries to be a convenient place to gather and access Microsoft's recommended methods. If your interested in my probably kludgy, error filled, and lacking enough cleanup code it's here: http://pastebin.com/v4GgDteY. The basic functionality seems to work although I haven't tested graph macro table recovery yet.
It occurred to me that Vista and Windows 7 users could benefit from being offered a list of previous versions of the file within my application if the Shadow Copy Service is on and there are previous copies. How do I do this?
I looked at a lot of web pages but found no easy to crib code. One possibility I guess would be to use vssadmin via the shell but that is pretty cumbersome. I just want to display a dialogue box like the Previous Versions property sheet and allow users to pick one of the previous versions. I guess I could just display the previous version property sheet via the shell by programmatically invoking the context menu and the "Restore previous versions choice", however I also want to be able to offer the list for Vista Home Basic and Premium Users who don't have access to that tab even though apparently the previous versions still exist. Additionally if it possible I would like to offer XP users the same functionality although I'm pretty sure with XP only the System files are in the shadow copies.
I looked at MSDN on the Shadow Copy Service and went through all the pages, I also looked at AlphaVSS and AlphaFS and all the comments. I'm kind of guessing that I need to use AlphaVss and AlphFS and do the following?
Find out the list of snapshots/restore points that exist on the computer.
Mount those snapshots.
Navigate in the mounted volumes to the Excel file the user wants to recover and make a list of those paths.
With the list of paths handy, compare with some kind of diff program, the shadow copies of the files with the original.
Pull out the youngest or oldest version (I don't think it matters) of those shadow copies that differ from the recovery target.
List those versions of the files that are found to be different.
This seems cumbersome and slow, but maybe is the fastest way to do things. I just need some confirmation that is the way to go now.
I finally decided to go ahead and start coding. Please make suggestions for speeding up the code or what do with files that are found to be different from the recovery file target. Is there a simpler way to do this with AlphaVSS and AlphaFS?
Private Sub Button1_Click_2(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'Find out the number of vss shadow snapshots (restore
'points). All shadows apparently have a linkable path
'\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy#,
'where # is a simple one, two or three digit integer.
Dim objProcess As New Process()
objProcess.StartInfo.UseShellExecute = False
objProcess.StartInfo.RedirectStandardOutput = True
objProcess.StartInfo.CreateNoWindow = True
objProcess.StartInfo.RedirectStandardError = True
objProcess.StartInfo.FileName() = "vssadmin"
objProcess.StartInfo.Arguments() = "List Shadows"
objProcess.Start()
Dim burp As String = objProcess.StandardOutput.ReadToEnd
Dim strError As String = objProcess.StandardError.ReadToEnd()
objProcess.WaitForExit()
Dim xnum As Integer = 0
Dim counterVariable As Integer = 1
' Call Regex.Matches method.
Dim matches As MatchCollection = Regex.Matches(burp, _
"HarddiskVolumeShadowCopy")
' Loop over matches.
For Each m As Match In matches
xnum = xnum + 1
'At the max xnum + 1 is the number of shadows that exist
Next
objProcess.Close()
Do
'Here we make symbolic links to all the shadows, one at a time
'and loop through until all shadows are exposed as folders in C:\.
Dim myProcess As New Process()
myProcess.StartInfo.FileName = "cmd.exe"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardInput = True
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
Dim myStreamWriter As StreamWriter = myProcess.StandardInput
myStreamWriter.WriteLine("mklink /d C:\shadow" & counterVariable _
& " \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy" _
& counterVariable & "\")
myStreamWriter.Close()
myProcess.WaitForExit()
myProcess.Close()
' Here I compare our recovery target file against the shadow copies
Dim sFile As String = PathTb.Text
Dim sFileShadowPath As String = "C:\shadow" & _
counterVariable & DelFromLeft("C:", sFile)
Dim jingle As New Process()
jingle.StartInfo.FileName = "cmd.exe"
jingle.StartInfo.UseShellExecute = False
jingle.StartInfo.RedirectStandardInput = True
jingle.StartInfo.RedirectStandardOutput = True
jingle.StartInfo.CreateNoWindow = True
jingle.Start()
Dim jingleWriter As StreamWriter = jingle.StandardInput
jingleWriter.WriteLine("fc """ & sFile & """ """ _
& sFileShadowPath & """")
jingleWriter.Close()
jingle.WaitForExit()
Dim jingleReader As StreamReader = jingle.StandardOutput
Dim JingleCompOut As String = jingleReader.ReadToEnd
jingleReader.Close()
jingle.WaitForExit()
jingle.Close()
Dim jingleBoolean As Boolean = JingleCompOut.Contains( _
"no differences encountered").ToString
If jingleBoolean = "True" Then
MsgBox(jingleBoolean)
Else
'I haven't decided what to do with the paths of
'files that are different from the recovery target.
MsgBox("No")
End If
counterVariable = counterVariable + 1
Loop Until counterVariable = xnum + 1
End Sub