Form causes Run-time error -2147352571 (80020005) - vba

I have a form which is partially filled in automatically from tables. There is a combo, where the number of transaction is chosen and then there is a textbox, where I want to fill in the partner name (searched in sheets).
I have spend some long time to figure out what am I having wrong in my code. In the end I managed the code work, but it looks very mysterious for me and it's not clean.
The original code:
Private Sub ComboTransaction_Change()
Dim ws_su As Worksheet
Set ws_su = Worksheets("Sale Unsettled")
TextPartner = ws_su.Range("SaleUnsettled_Start").Offset(Application.WorksheetFunction.Match(Val(ComboTransaction), ws_su.Range("SaleUnsettled_Transactions"), 0), 1)
End Sub
The "solution":
Private Sub ComboTransaction_Change()
Dim ws_su As Worksheet
Set ws_su = Worksheets("Sale Unsettled")
PartnerValue = ws_su.Range("SaleUnsettled_Start").Offset(Application.WorksheetFunction.Match(Val(ComboTransaction), ws_su.Range("SaleUnsettled_Transactions"), 0), 1)
TextPartner = PartnerValue
End Sub
Why I have to do it via the PartnerValue, that's a mystery for me. Not only it bothers me because it's messing up the code (there are more values which I have to fill in the same way), but I also have another forms (Purchase etc), where it works without this strange patch.
I would like to get rid of if so if you have any idea what's wrong, I will appreciate your message.
The only difference between TextPartner and PartnerValue is that TextPartner is a TextBox in the form and PartnerValue isn't.

The Run-time error means that it is a Type mismatch.
Try to use
TextPartner.Text = ws_su.Range("SaleUnsettled_Start").Offset( _
Application.WorksheetFunction.Match(Val(ComboTransaction), _
ws_su.Range("SaleUnsettled_Transactions"), 0), 1)

Related

How do I change the text of multiple bookmarks by stepping through an array?

Sub initialize()
For boxNum = 1 To 10
vaultValuesForm.Controls("h" & boxNum).Value = ""
vaultValuesForm.Controls("d" & boxNum).Value = ""
Next boxNum
vaultValuesForm.Show
End Sub
Sub button_Populate_Click()
Dim array_h(9) As String, array_d(9) As String
For boxNum = 0 To 9
array_h(boxNum) = vaultValuesForm.Controls("h" & (boxNum + 1)).Value
array_d(boxNum) = vaultValuesForm.Controls("d" & (boxNum + 1)).Value
Next boxNum
Call populateTable(array_h(), array_d())
End Sub
Sub populateTable(array_0() As String, array_1() As String)
For x = 1 To 4
ThisDocument.Bookmarks("bd" & x).Range.Text = array_0(0)
Next x
End Sub
I have tested the functionality of this code at various points, and it works flawlessly right up until this line:
ThisDocument.Bookmarks("bd" & x).Range.Text = array_0(0)
Specifically, until it reaches = array_0(0). In its current state, reaching this point in the Sub results in "Run-time error '5941': The requested member of the collection does not exist." Same deal when I originally tried using = array_0(x) (which is ultimately what I'm trying to accomplish). However, if replaced with something direct such as = "AA", it works. How do I phrase this bit properly to set the bookmark values to those within the array?
Note: In case you're wondering, the arrays are being referenced and passed properly; I tested this by changing the loop to comments and using MsgBox() with various array elements.
The answer from comments. The issue I wasn't aware of was that the bookmarks were being deleted after running the module, so it wouldn't work again unless the bookmarks were created again.
Are you sure the bookmarks bd1...bd4 are still there in the document? Because a bookmark's range.text deletes the bookmark, so if you want to be able to repeat the bookmark text assignments you have to recreate the bookmarks after assigning the texts. FWIW I ran your code and it was fine when bd1..bd2 etc. existed but threw 5941 the next time. (This is quite a common problem!) – slightly snarky Sep 3 at 8:37
So, for the official answer to my question, the way I had done it initially is how; it just couldn't be repeated.

Runtime error 438 on remove dynamically added userform control

I've got the following code:
Private Sub cboA_change()
'Something to determine number of controls there should be, variable gC
'Something to determine number of controls there are, variable nC
'The first time the code runs, the following code runs:
For i = nC to gC
frmA.Frame1.Controls.Add("txtGroup" & i)
Next
'The second time the code runs, the following is executed:
For i = 7 To nC
Me.Frame1.Controls("txtGroup" & i).Remove 'ERROR HERE
Next
For i = nC to gC
frmA.Frame1.Controls.Add("txtGroup" & i)
Next
End Sub
Something like this, the code is way bigger and I tried to clear it up so if the structure doesn't seem right, that doesn't matter really.
I debugged the Add statement and I know there is a control added to the userform, called txtGroup7. However, when I later try to remove this control, I get Run-time Error 438: Object Doesn't Support This Property or Method. I tried changing the code to:
Me.Frame1.Controls.Remove ("txtGroup" & i)
But this didn't work either.
Can anybody point me in the right direction?
Edit:
I know the help says the following:
"This method deletes any control that was added at run time. However,
attempting to delete a control that was added at design time will
result in an error."
But since the control is added in run-time (dynamically, with VBA code) this shouldn't be a problem, right?
Edit 2:
I don't get why this works, but it seems to work:
q=0
While q < Me.Frame1.Controls.Count
If Me.Frame1.Controls(q).Name = "txtGroup7" Then
Me.Frame1.Controls.Remove q
Else
q = q + 1
End If
Wend
You must have something else wrong in your code, because Removeshould be working. Tried :
Private Sub ToggleButton1_Click()
If ToggleButton1.Value = True Then
Me.Frame1.Controls.Add "Forms.TextBox.1", "Text1", True
Else
Me.Frame1.Controls.Remove "Text1"
End If
End Sub
on a UserForm with a ToggleButton and a Frame and it correctly add and remove the TextBox when pressed.

DataGridView properties not being set when called from Form Load

I'm having a really strange issue with the DataGridView control in a VS2008 / .NET 3.5 winforms project. I have a simple form with a grid. In the form constructor I call a function to bind the grind to a DataTable, and then loop through the rows setting the background colour of the last cell to LightGrey and the cell itself to read-only if the column value is true. After the form finishes loading the code didn't work i.e. the cells are not set to LightGrey and are not read-only (even though when I step through the code I can see the properties being set). I then call the function again from a button, but this time the colour is changed to LightGrey and the cell is made read-only i.e. the code works.
CODE:
Dim dgr As DataGridViewRow
For i_DsRow As Integer = 0 To ds.Tables(0).Rows.Count - 1
dr = ds.Tables(0).Rows(i_DsRow)
For i_row As Integer = 0 To DgSearch.Rows.Count - 1
dgr = DgSearch.Rows(i_row)
If dr("DsColoumn1").ToString.ToUpper = dgr.Cells("DgColoumn1").Value.ToString.ToUpper Then
If Val(dr("Coloumn2").ToString) = 3 Then
dgr.Cells("SomeColomname").Value = dr("SomeColoumName2").ToString
If dgr.Cells("SomeColomname3").Value.ToString <> "" Then dgr.Cells("SomeColomname3").Value &= ", "
dgr.Cells("SomeColomname3").Value &= dr("SomeColoumName2").ToString
SetCellColor(dgr.Cells("SomeColomname"), dgr.Cells("SomeColomname3"))
End If
Exit For
End If
Next
Next
Private Sub SetCellColor(ByVal resultCell As DataGridViewCell, ByVal ColorCell As DataGridViewCell)
If resultCell.Value.ToString().ToUpper = "A".ToUpper Or resultCell.Value.ToString().ToUpper = "B".ToUpper Then
ColorCell.Style.BackColor = Color.FromName("Red")
ElseIf resultCell.Value.ToString().ToUpper = "C".ToUpper Or resultCell.Value.ToString().ToUpper = "D".ToUpper Then
ColorCell.Style.BackColor = Color.FromName("MediumSeaGreen")
Else
ColorCell.Style.BackColor = Color.FromName("Yellow")
End If
End Sub
Thanks for adding the code. I would suggest putting all formatting in the CellFormatting event of the DataGridView.
There are a couple of gotchas that you have to watch, which looking at your code shouldn't be a problem but to be aware of:
This runs for each cell in the grid. Therefore Database lookups are a really bad idea.
You do best to get values where possible from the eventargs parameter of the method
If you need a code sample, I believe there are some good c# examples (possibly vb to) this one for example.

Modify Chart properties in Access report via VBA (error 2771)

I am building an Access report (2010 version), and would like to be able to customize it based on the user's selections on a form. When I run it, I get error 2771: The bound or unbound object frame you tried to edit does not contain an OLE object.
This is the code to pass the parameter:
Private Sub Command120_Click()
DoCmd.OpenReport ReportName:="rpt_EODGraph", View:=acViewPreview, _
OpenArgs:=Me!Text0.Value
End Sub
This is the code to open the report.
Private Sub Report_Open(Cancel As Integer)
Dim ch As Chart
Set ch = Me.Graph3.Object.Application.Chart 'This line generates the error
ch.ChartTitle.text = OpenArgs
End Sub
I've found at least one person saying that this is not actually possible to do on a report. (http://www.access-programmers.co.uk/forums/showthread.php?t=177778&page=2 Note that this is page 2 of a 2 page forum discussion...) Can anyone corroborate or refute?
Apparently the Report has to have some kind of focus before OLE objects are accessible.
It is enough if you click on it or set the focus to something:
Private Sub Report_Open(Cancel As Integer)
Dim ch As Object
Me.RandomButton.SetFocus
Set ch = Me.Diagramm11.Object
ch.ChartTitle.Text = "Hello"
End Sub
This works. I just set a button on the report that gets the focus. Perhaps you find something more elegant ;)

VSTO Document Customization: Missing Control Sheet Reference Unless other Actions taken first

So I have a work around to my problem, but I don't really understand the problem, and my work-around is crude. I have a document level customization that can insert sheets from other documents not included in the customized document:
Private Sub LabReportTemplateAdder()
Dim ReportTemplate As Excel.Workbook
CurrentRun = Marshal.GetActiveObject("Excel.Application")
ReportTemplate = CurrentRun.Workbooks.Open("C:\Reports\Templates\" & LabReportListBox.SelectedItem())
ReportTemplate.Worksheets(1).Move(Before:=Globals.ThisWorkbook.Sheets(5))
End Sub
This script actually works fine every time in the deployment. But when I try to modify the added template (ie add information from a database) the modifications (many different actions) all fail with a missing reference error:
"This document might not function as expected because the following control is missing: Sheet5. Data that relies on this control will not be automatically displayed or updated, and other custom functionality will not be available. Contact your administrator or the author of this document for further assistance."
An examples of the type of code that fails:
Private Sub AllMaterialsAdder(xxDataGridView As DataGridView, CostColumnID As Double, InsertColumnID As Double, CountColumnID As Double, DescriptionIndex As Integer, CostIndex As Integer)
CurrentSheet = Globals.ThisWorkbook.ActiveSheet
If CurrentSheet.Name = NameSet Then 'this is abbreviated test to check make sure only the sheets we need are added
MsgBox("The active sheet isn't a Lab Report. It's " & CurrentSheet.Name & ".")
Else
Dim ItemCount As Double
ItemCount = CurrentSheet.Cells(1, CountColumnID).value
For Each row As DataGridViewRow In xxDataGridView.SelectedRows
CurrentSheet.Cells((4 + ItemCount), InsertColumnID).value = xxDataGridView.Item(DescriptionIndex, row.Index).Value
CurrentSheet.Cells((4 + ItemCount), CostColumnID).value = xxDataGridView.Item(CostIndex, row.Index).Value
ItemCount = ItemCount + 1
Next
End If
End Sub
or
Private Sub MaterialSummaryUpdater()
CurrentSheet = Nothing
Globals.MaterialSummaryWorksheet.UsedRange(5, 26).Clear()
For Each Me.CurrentSheet In Globals.EOSWorkbook.Worksheets
If CurrentSheet.Name <> NameSet Then 'this is abbreviated test to check make sure only the sheets we need are added [excluding NameSet]
Dim CurrentCount1, CurrentCount2, CurrentCount3, MasterCount1, MasterCount2, MasterCount3 As Int32
CurrentCount1 = CurrentSheet.Cells(1, 28).Value
CurrentCount2 = CurrentSheet.Cells(1, 33).Value
CurrentCount3 = CurrentSheet.Cells(1, 39).Value
If CurrentCount1 > 0 Then
MasterCount1 = Globals.MaterialSummaryWorksheet.Cells(2, 3).Value
Globals.MaterialSummaryWorksheet.Range(Globals.MaterialSummaryWorksheet.Cells((5 + MasterCount1), 1), Globals.MaterialSummaryWorksheet.Cells((4 + MasterCount1 + CurrentCount1), 6)).Value = CurrentSheet.Range(CurrentSheet.Cells(4, 25), CurrentSheet.Cells((3 + CurrentCount1), 30)).Value
End If
If CurrentCount2 > 0 Then
MasterCount2 = Globals.MaterialSummaryWorksheet.Cells(2, 8).Value
Globals.MaterialSummaryWorksheet.Range(Globals.MaterialSummaryWorksheet.Cells((5 + MasterCount2), 7), Globals.MaterialSummaryWorksheet.Cells((4 + MasterCount2 + CurrentCount2), 10)).Value = CurrentSheet.Range(CurrentSheet.Cells(4, 31), CurrentSheet.Cells((3 + CurrentCount2), 35)).Value
End If
If CurrentCount3 > 0 Then
MasterCount3 = Globals.MaterialSummaryWorksheet.Cells(2, 13).Value
Globals.MaterialSummaryWorksheet.Range(Globals.MaterialSummaryWorksheet.Cells((5 + MasterCount3), 12), Globals.MaterialSummaryWorksheet.Cells((4 + MasterCount3 + CurrentCount3), 16)).Value = CurrentSheet.Range(CurrentSheet.Cells(4, 36), CurrentSheet.Cells((3 + CurrentCount3), 40)).Value
End If
End If
Next
End Sub
I should note that this doesn't happen on the computer I'm developing on, but only in deployment, which might make it related to this question or this one.
Though I feel like the problem is bit different for me. First, all of the machines I am trying to deploy this on do have VSTO Tools for Office installed. Secondly, if I run a script that calls one of the Named Sheets within the customized document, it works. Simply adding a worthless variable before I ever add in a sheet seems to fix the problem:
Dim currentcount As Int32 = Globals.HistologyLaborSummaryWorksheet.Cells(2, 11).value
But if I call that after a sheet has been added it doesn't matter it will fail. My simple work around was to add this to the LabReportTemplateAdder sub, but I still don't understand why it should fail, and why that would fix it. Clearly the sheets exist, but I don't know if it has something to do with modifying the sheet index or if the worksheets need to be registered somewhere similar to the ROT problem I ran into earlier.
I'm looking for a better solution if there is one, and an explanation as to what is really failing here.
Thanks.
EDIT:
I'm running into this now in more places, and again, the work around seems crude. Here is a full error:
Microsoft.VisualStudio.Tools.Applications.Runtime.ControlNotFoundException:
This document might not function as expected because the following control is missing:
Sheet5. Data that relies on this control will not be automatically displayed or updated,
and other custom functionality will not be available. Contact your administrator or the
author of this document for further assistance. --->
System.Runtime.InteropServices.COMException: Programmatic access to the Microsoft Office
Visual Basic for Applications project system could not be enabled. If Microsoft Office
Word or Microsoft Office Excel is running, it can prevent programmatic access from being
enabled. Exit Word or Excel before opening or creating your project.
at Microsoft.VisualStudio.Tools.Office.Runtime.Interop.IHostItemProvider.GetHostObject(String primaryType, String primaryCookie, IntPtr& hostObject)
at Microsoft.VisualStudio.Tools.Office.Runtime.DomainCreator.ExecuteCustomization.Microsoft.Office.Tools.IHostItemProvider.GetHostObject(Type primaryType, String primaryCookie)
at Microsoft.Office.Tools.Excel.WorksheetImpl.GetObjects()
--- End of inner exception stack trace ---
at Microsoft.Office.Tools.Excel.WorksheetImpl.GetObjects()
at Microsoft.Office.Tools.Excel.WorksheetImpl.GetPrimaryControl()
at Microsoft.Office.Tools.Excel.WorksheetImpl.get_Cells()
at Microsoft.Office.Tools.Excel.WorksheetBase.get_Cells()
This looks relevant based on the fact that you are inserting sheets.