Atl LED
Atl LED

Reputation: 666

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()

Upvotes: 0

Views: 1555

Answers (1)

mr_plum
mr_plum

Reputation: 2437

This looks relevant based on the fact that you are inserting sheets.

Upvotes: 1

Related Questions