I'd like to display the data of my Access database on a separate monitor for the students of a library.
What software or Access tool should I use for this please?
The database should be the only thing the students have access to, meaning they can't access other apps on the computer.
Thank you very much for your time.
Firstly: relying on your Access app being on the separate monitor is NOT AT ALL secure if you need to prevent user access to other applications (for so, so many reasons, but press Windows+E for an example).
Secondly: Microsoft Access will open up on the same monitor on which it was last open. Though I assume you know that and wouldn't be asking if that were suitable to you.
Thirdly: here is VBA code that actually moves the Access application window. It DOES NOT determine where the second monitor is - you have to change the value -1500 according to the screen specs (either manually and hard-coded, or better, Google for some code to determine the position of the second monitor). On my setup, it -1500 happens to end up around the middle of the second monitor which I happen to have on the left (possibly unusual?). If your second monitor is on the right, then I think you'll need a positive value that is greater than the resolution of the fist monitor. It just has to be somewhere within the second screen - not necessary perfectly on the edge because the code then maximises the window. Upshot: you need to experiment with that.
What it does:
Take window out of maximised mode (necessary to move it properly).
Move it such that the top-left corner is somewhere in the second screen.
Maximise the window.
VBA:
Declare Function winapi_ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As Long, ByVal nCmd As Long) As Long
Declare Function winapi_MoveWindow Lib "user32" Alias "MoveWindow" (ByVal hwin As Long, ByVal X As Long, ByVal Y As Long, ByVal dx As Long, ByVal dy As Long, ByVal fRepaint As Long) As Long
Const SW_SHOWNORMAL = 1
Const SW_SHOWMAXIMIZED = 3
Public Sub MoveAccessWindow
winapi_ShowWindow Access.Application.hWndAccessApp, SW_SHOWNORMAL
winapi_Movewindow Access.Application.hWndAccessApp , -1500, 0, 1000, 1000, True
winapi_ShowWindow Access.Application.hWndAccessApp, SW_SHOWMAXIMIZED
End Sub
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
My app's external processes each poll a boolean to see if there is work to do. I now want to check that variable in a Timer event to cut down the 'not responding' messages.
A Timer object has to be placed on a form, which seems to cause some limitations.
Launching the event from a form with Me.Show (vbModal) works great. Only I don't want to actually show that form, I just want to use the timer. Trying to hide the form using Me.Hide then loses the Modal behavior which I need, so that's not a good workaround.
I tried launching the event from a class but it exhibits the same unwanted behavior as Me.Hide: Processing returns to the caller rather than staying in the timer event sub waiting for work.
Is there any way to implement an event based on Timer which doesn't require showing a form and does not immediately return to the caller? The external processes have no screen IO and none is desired.
You can look into using the SetTimer function from the Windows API. Add the following code in a Module and user TimerStart with an interval in milliseconds:
Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Function TimerStart(ByVal p_lngInterval As Long) As Long
' Start timer
TimerStart = SetTimer(0, 0, p_lngInterval, AddressOf TimerCallBack)
End Function
Public Sub TimerCallBack(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
' Handle your polling here
End Sub
You do not need a Form so this should suit your needs.
You can also use Sleep from the Windows API in conjuction with Timer to keep your EXE running:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Sub Main()
TimerStart 2000
Do While True
DoEvents
Sleep 1000
Loop
End Sub
See these other answers for more details:
How to make safe API Timers in VBA?
How do I delay code execution in Visual Basic (VB6)?
So, I'm not really sure how to even title this kind of question. I've tried searching for an answer, but maybe I'm not using the right term(s). Here's the basic idea:
I have a form that contains a TreeView on the left side acting as an "Options" form. Based on the node selected in the TreeView, the appropriate Panel is displayed on the right with the controls for the selected setting. Since I'm only in the beginning of designing this form, I'm not sure how many options I'll have in the end; and thus, I'm not sure how many Panels I will have in the end.
Options Screen
Initially, the problem has been solved by placing all of the Panels inside a single parent Panel and creating a loop (or 4) to add all Control.Panel objects to a Control Array. This allows me to display the correct Panel based on the selected node, dynamically. The problem is...I currently only have a single sub-level (i.e. Parent and Parent-Child nodes), thus my array only needs to be 2-Dimensional. But should I decide to add another level (i.e. Parent-Child-Child), my array would need to be 3-Dimensional.
Imports System.ComponentModel
Imports System.Text.RegularExpressions
Public Class frm_options
Dim all_controls(,) As Control = {} 'Array of panel controls inside of panel_container.
Private Sub frm_options_Load(sender As Object, e As EventArgs) Handles Me.Load
'Fill (and resize as needed) the all_controls(,) array with the panel controls based on their x,y coordinates by name.
'Arrange ALL panels to the correct location.
Dim x As Integer = 0
Dim y As Integer = 0
For Each panel_control As Control In panel_container.Controls
If TypeOf (panel_control) Is Panel Then
'Find the total amount of x,y panels that we need to fit into our array.
'Find x,y dimension that panel should fit into array based on name [i.e. panel_1_0(0,0), panel_1_1(0,1), panel_2_0(1,0), panel_2_1(1,1), etc.]
Dim xy As MatchCollection = Regex.Matches(panel_control.Name, "panel_(\d)*_*(\d)")
For Each m As Match In xy
For Each cx As Capture In m.Groups(1).Captures
'For every x
If (cx.Value > x) Then
x = cx.Value
End If
For Each cy As Capture In m.Groups(2).Captures
'For every y in x
If (cy.Value > y) Then
y = cy.Value
End If
'Because we start our panel naming convention at 1_0, we must subtract this from our X value but not Y.
ReDim Preserve all_controls(x - 1, y)
all_controls(cx.Value - 1, cy.Value) = panel_control
Next
Next
Next
End If
Next
'At this point, x = maximum x coordinates needed, y = maximum y coordinates needed and all_controls contains a list of Panels for the TreeView.
End Sub
Private Sub options_tree_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles options_tree.AfterSelect
'All below examples assume there is a single parent and child node.
'If there is a need for a child in a child node, change Level to > 1 (or however many childs needed)
If (options_tree.SelectedNode.Level > 0) Then
'If the selected node is a child node...
For Each control_panel In all_controls
If (control_panel IsNot Nothing) Then
If (control_panel Is all_controls(options_tree.SelectedNode.Parent.Index, options_tree.SelectedNode.Index + 1)) Then
control_panel.Visible = True
Else
control_panel.Visible = False
End If
End If
Next
Else
'If the selected node is a parent node...
For Each control_panel As Control In all_controls
If (control_panel IsNot Nothing) Then
If (control_panel Is all_controls(options_tree.SelectedNode.Index, 0)) Then
control_panel.Visible = True
Else
control_panel.Visible = False
End If
End If
Next
End If
End Sub
Forgive my ugly coding...I'm sure there are much easier ways to achieve this - but I only code as a hobby and have never taken any courses on it. As you can see, this code allows me to add as many nodes and respective panels as needed (as long as I continue to use the right naming convention) without having to change any of my code to implement the new controls. But should I add another level to the TreeView, I will need to modify the code to use a 3-Dimensional array instead.
So in short, I'm sure there is a completely different method I should be using. If so, what would it be? Again, I want to have a code that allows me to add nodes, levels, and panels to my form without having to change the code to control these elements.
Edit: Through my research, I've looked into the Collection class. My problem with using this is that I don't think I would be able to reference which panel to display based on the Index of the selected node.
I am working on a very old visual basic project. I have to rewrite the load and save function of the project. Therefore I wanted to create an array of controls which have all relevant textboxes and checkboxes included. I want to iterate through that array to be able to save the data into a textfile or load from it.
I have looked on the internet of how you can define those arrays, but it doesn't seem to work for me. Maybe I am doing something wrong, cause I am not an expert in Visual Basic.
I have tried to make it work this way:
Dim tbList As TextBox = { Form1.Text1, Form1.Text3, _
Form1.Text10, Form1.Text11, Form1.Text12, Form1.Text13, _
Form2.Text1, Form2.Text3, Form2.Text4, Form2.Text5, _
Form2.Text10, Form2.Text11, Form2.Text12, Form2.Text13, _
Form3.Text1, Form3.Text3, Form3.Text4, Form3.Text5, _
Form3.Text10, Form3.Text11, Form3.Text12, Form3.Text13, _
Form3.Text17, Form3.Text18, Form3.Text19, Form3.Text20, _
Form4.Text1, _
Form5.Text1, Form5.Text2, Form5.Text3, _
Form6.Text2, _
Form7.Text2}
Or with a list:
Dim tbList As New List(Of Controls)
The thing is Visual Basic always tells me there are some kind of compiling issues. There is no real explantation for this issue in VB, so I am asking here.
Your code isn't compiling because it is vb.net code. It should go without saying (but I'll say it anyway) that vb6 and vb.net are not the same thing.
If you want to use an array, you will have to dimension the array with a number that is one less than your number of textboxes (if I counted correctly there are 32 in your example):
'// array is zero based so 0 to 31 = 32 items
Dim tbList(31) As TextBox
tbList(0) = Form1.Text1
tbList(1) = Form1.Text3
'//...I'll leave the rest as an exercise for the programmer
tbList(31) = Form7.Text2
Dim i As Integer
Dim tb As TextBox
'// To loop and work with each textbox
For i = 0 To UBound(tbList)
Set tb = tbList(i)
'// do something with tb
Next
An easier way to do it, however, is to work with a collection:
Dim tbList As New Collection
tbList.Add Form1.Text1
tbList.Add Form1.Text3
'//...I'll leave the rest as an exercise for the programmer
tbList.Add Form7.Text2
Dim tb As TextBox
'// To loop and work with each textbox
For Each tb In tbList
'// do something with tb
Next
Yes, you can use a collection if you want to go to the trouble. But an even easier way to work with it is to use VB6's (now obsolete) control array implementation. Most of us were disappointed when we found it was no longer available in .Net!
All you have to do to get control arrays in VB6 is create a bunch of controls with the same name. (They do have to be the same type of control; you can't make arrays of, say, text boxes and combo boxes.) Start with one text box, name it what you want, and copy it. You will be asked if you want to create a control array. Say yes, copy as many as you want. You will notice that the Index property is no longer blank, starting with 0 and incrementing from there. You will also notice that all of the event handlers have an "Index As Integer" argument to them. This way, you can use the same event handler for all of them, evaluating the Index argument to find out which member of your array is firing the event.
Here is the old doc for it. Microsoft makes it hard to find. :)
I am trying to print a report where we have several different components within the xaml.
By what I`ve found, when printing, you have to treat every UIelement as a single one, thus if the desiredSize is bigger than the AvailableSize you have to activate the flag HasMorePages.
But here comes the problem.
My user can write as much text as he/she wants on the grid, therefore, depending on the amount, the row expands and goes off the printable area, as you can see on the picture below.
I thought about giving a whole page to the grid, but it was to big still, which got me into a loop where the DesizedSize was always bigger than the PrintableArea.
My code is not very different from any source you find on internet when searching for Multiple Page printing.
It is based on this http://eswarbandaru.blogspot.com.au/2011/02/print-mulitple-pages-using-silverlight.html , but using Stackpanels instead of Textboxes.
Any idea?
Thank you in advance.
First you need to work out how many pages are needed
Dim pagesNeeded As Integer = Math.Ceiling(gridHeight / pageHeight) 'gets number of pages needed
Then once the first page has been sent to the printer, you need to move that data out of view and bring the new data into view ready to print. I do this by converting the whole dataset into an image/UI element, i can then adjust Y value accordingly to bring the next set of required data on screen.
transformGroup.Children.Add(New TranslateTransform() With {.Y = -(pageIndex * pageHeight)})
Then once the number of needed pages is reached, tell the printer to stop
If pagesLeft <= 0 Then
e.HasMorePages = False
Exit Sub
Else
e.HasMorePages = True
End If
Or if this is too much work, you can simply just scale all the notes to fit onto screen. Again probably by converting to UI element.
Check out this link for converting to a UI element.
http://www.codeproject.com/Tips/248553/Silverlight-converting-to-image-and-printing-an-UI
Hope this helps
I have developed a sample WPF application that has one window with one button
When application is opened, if observed from task manager, memory occupied: 12.3 MB
Dim b As Boolean = False
Private lst As List(Of String)
Private Sub Btn_Close(sender As Object, e As RoutedEventArgs)
If b = False Then
If lst Is Nothing Then lst = New List(Of String)
For i As Integer = 0 To 30
lst.Add(Convert.ToBase64String(IO.File.ReadAllBytes("d:\test.txt"))) 'memory increases, test.txt file is a 2MB file
Next
'do some operations with lst object
'memory occupied: 133MB
'now again click the same button, it will go to else case now (cause of the last statement)
Else
lst.Clear()
If MsgBox("GC.Collect()?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
GC.Collect()
'in this case, memory occupied: 13MB
Else
'in this case, memory occupied: 133MB, not cleared
End If
End If
b = Not b
End Sub
Only when GC.Collect() statement is executed memory is released, otherwise the memory stays at 133MB only.
I have requirement in a way when click on any button, a new window opens as showdialog that contains a grid with thousands of records, say: 6000 to 1Lakh, here I do some operations with the selected records (here memory increases) and then closes the window. After closing the window, the memory is not released, I explicitly have to execute the statement GC.Collect()
Is there any thing wrong in the code? or why do I need to explicitly call GC.Collect as CLR will take care of it automatically? (in my application, if I repeat above and don't use GC.Collect, I get outofmemory exception after some time)
There's nothing wrong with your code, and there's nothing wrong with your memory consumption either. There is no guarantee that closing your form will immediately release the memory; indeed, GC will reclaim the memory when it needs to, which is very often not when a developer expects it to.
Garbage collection in .NET fires automatically in response to allocations of memory - that is, when you try to declare an object that doesn't fit in the heap's current Gen0, a garbage collection will occur.
The real question to ask here is: why do you have an issue with the memory staying at 133MB? Is it causing you a problem? Unless you have a specific requirement for this memory to be collected, I'd say don't GC.Collect(), and let the framework work it out for you.
(It's worth noting that calling GC.Collect() manually often has a negative effect on the long-term memory consumption of an application.)