unfortunately I was not able to answer my question with the help of Google.
I created a Userform with a frame which contains different controls (Textbox, Combobox, Listbox, Label).
Usually the inputs are saved directly to a workbook after the user presses the OK button.
But there is one special situation, where I want the user to fill in several of these Input Userforms one after another and save all the contents of the Userforms at last.
Therefore I created a global Object-Array where I saved the Input-Frames of each Userform, the user filled in.
At the end I wanted to go through all these frames and its controls and save the contents in one step.
My already existing save function uses a frame as input, so I wanted to loop through my frame array.
Here is my example code:
(conArr is a global Object Array variable)
Public Sub btnOK_Click()
conArrRow = 0
ReDim Preserve conArr(conArrRow)
Set conArr(conArrRow) = frmData.frameDataInput
Unload Me
End Sub
After the Userform is unloaded I get back to the main code.
For Each ctl In conArr(0).Controls
MsgBox ctl.Name
Next
Here I get the error at line: For Each ctl In conArr(0).Controls
Microsoft Visual Basic
Run time error -2147418113 (8000ffff)
Automation error
Catastrophic failure.
I guess the problem occurs because the form with its frame is already unloaded and does not exist anymore. If I put the part of the main code directly to the end of btnOK_Click it works.
I appreciate any help.
Thanks in advance.
Related
So I'm trying to set up a VB Windows Form that reads data from an array and displays it in a label (and sometimes textboxes so it could be edited). The array contains strings and I know they are stored properly because I can make them appear properly when using MsgBox.
For example
MsgBox(ArrayName(0,0))
works, but when I use
textboxname.Text = ArrayName(0,0)
I get a build error. I thought adding ".ToString" at the end might solve this, and the build error is gone, but then the textbox says "System.Char[]" instead of the value that I put inside the array. The MsgBox shows this as well, if I put ".ToString" at the end.
Thank you in advance for your help!
Edit: The array is declared via the code:
Module ModuleName
Public ArrayData(20, 6) As Array
End Module
so that I can edit it outisde of any specific subroutines.
The array only contains the characters (delimiter is comma): 0,1,2,3,4,5,6 in the first row and q,w,e,r,t,y in the second row.
I keep trying to create a new record expecting a new blank form to show up but all of the info from the previous form shows up.
I need a blank form to enter data but i also need to save all of my previous forms. Overall, I want to keep adding onto my records. But somehow it won't let me.
If I'm understanding correctly you open a form but it is showing the data you previously entered? if it is that you want avoid seeing the previous data and just have a blank for for entry that you should set the form properties Data Entry to Yes
Depending on whether or not you have a bound form, Kefash' answer could work.
If you have an unbound form however, it will not.
If you do have an unbound form, the simplest way is to just loop through all the controls and empty them.
For example:
Private Sub save_Click()
Dim ctl As Control
For Each ctl In Me.Controls
Select Case ctl.ControlType
Case acListBox
If Len(ctl.ControlSource) = 0 Then
ctl.Value = Null
End If
Case acCheckBox
ctl.Value = 0
Case acTextBox
ctl.value = ""
End Select
Next
End Sub
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'm new to creating user forms in VBA. I've been using VBA macros for a while now though so I understand some about them. Right now I'm creating a spreadsheet for a user where I'm using a user form with a list box. I have a lot of code in a regular module and need to refernce the module to fill the listbox. What I have right now is this:
Private Sub StartButton_Click()
Dim Number
Call GetTellerNames
For Number = 0 To 40 Step 1
If GetTellerNames(Number) <> "" Then
ListBox1.AddItem (GetTellerNames(Number))
End If
Next
End Sub
When I run this I get an error saying
Sub of Function not defined
How do I fix this so that I can use the array in my module to fill the list box? I've already got the code to fill the array working.
Here is the code for the GetTellerNames sub in the module:
Private Function GetTellerNames()
GetTellerNames = FindOthers(BranchNumber, TellerCode, 2)
End Function
It is using global variables that are set in other parts of the code. I can post all of the code if necessary.
Since the GetTellerNames() code lies within a standard module you need to change the access modifier to public in order to be able to access that method/sub from the UserForm1 object module.
We use DataGridViews throughout our UI... most are data-bound to some backing table... most of those through a BindingSource.
They all have supported Ctrl+C to Copy tabular data out (so you can paste into Excel or Word tables, etc.). That was easy... it's built-in... just set MultiSelect true and ClipboardCopyMode to EnableWithAutoHeaderText (or one of the other Enable... settings).
Our users have requested us to similarly support Ctrl+V to Paste tabular data copied from Excel etc. Unfortunately, that is not nearly so easy. I created a generic utility method PasteStringTable(DataGridView) that will pull the tabular data off the Clipboard and then paste it into the selected cells of the argument DataGridView. I have that working except for one key issue:
If the DataGridView has AllowUserToAddRows set true, and the user is in that magic "new row" at the bottom, then I wanted to add rows for each row on the Clipboard. But the problem is, nothing I do programmatically ever seems to get it to actually add that row... I've tried everything that I can think of (or find via Bing or Google):
(1) I tried doing BeginEdit / EndEdit on the DataGridView.
(2) I tried first setting the DataGridView.CurrentCell to the cell I was about to edit, then DataGridView.BeginEdit(true), then edit the cell by setting its Value property, then DataGridView.EndEdit().
(3) I tried doing #2, but where I did SendKeys.Send(value) instead of .Value = value.
(4) I tried doing DataGridView.NotifyCurrentCellDirty(true) in the middle of the above.
(5) I tried modifying the underlying data source first by manually doing DataGridView.Rows.Insert(index, 1) to try to force in a new row before I pasted into it... but that throws an exception since my DataGridViews are data-bound. (NOTE: I do not want to hard-code specific access to the underlying data because I want it to work like Paste where the data copied lines up visually with the DataGridView's columns.)
(6) Many other variations...
In the end, most attempts result in the same behavior: you can see that the bottom row gets modified... you can see the first row of the data you copied show up in that magic "new row", until you click out of the row and the row goes blank again... unless you manually edit it, it never gets added to the underlying data. Even if I try doing SendKeys.SendWait(...), it still doesn't act like it would if I typed in that data.
How do I programmatically get that magic "new row" to act like it would if I typed in the pasted in data??
(Surely I am not the first person to want to paste tabular data into DataGridViews.)
After much trial and error, this is the pattern I came up with that works well in most cases. This is pure guesswork, though, so if anybody knows how it is supposed to work, please let us know. Anyway, here's what I've got working:
DataGridViewCell cell = dgv[colIndex, rowIndex];
if (!cell.ReadOnly) // && (evenIfNotSelected || cell.Selected)) // Selected is not stable in some cases
{
if (!cell.OwningRow.IsNewRow)
cell.Value = cellData;
else
{
dgv.CurrentCell = cell;
dgv.BeginEdit(true);
dgv.NotifyCurrentCellDirty(true);
//SendKeys.SendWait(cellData);
cell.Value = cellData;
//dgv.CommitEdit(???);
dgv.EndEdit();
//PSMUtility.DoMessages();
// Do it again to try to overwrite the default value that might get injected by EndEdit adding the row
cell.Value = cellData;
}
}
Also i try many solution and finally it's work in my case.
private void calculationGrid_KeyPress(object sender, KeyPressEventArgs e)
{
if ((int)e.KeyChar == 22 && Control.ModifierKeys == Keys.Control)
{
calculationGrid.CurrentCell.Value = Clipboard.GetText().Replace("\r", "").Replace("\n", "").Trim();
calculationGrid.BeginEdit(true);
calculationGrid.NotifyCurrentCellDirty(true);
calculationGrid.EndEdit();
}
}