VB.NET en MS Excel koppeling (Grasshopper)

Status
Niet open voor verdere reacties.

patrickmarinus

Gebruiker
Lid geworden
15 mei 2013
Berichten
6
Hallo allemaal,

Ik ben nieuw op het forum en heb al gezocht naar een antwoord op mijn vraag maar heb deze (nog) niet kunnen vinden.

Momenteel werk ik aan een koppeling tussen Grasshopper + Rhinoceros en Excel met behulp van VB.NET (Visual Basic).
Grasshopper verzorgd de parametrische input voor een 3D model in Rhinoceros, Excel gebruik ik hierbij als berekeningsprogramma.
Op dit moment kom ik niet verder met het aanleggen van deze koppeling. Dit komt vooral door mijn gebrek aan kennis over Visual Basic.
Wat ik graag zou willen is dat het VB.NET component in Grasshopper (met behulp van een VB.NET script) automatisch mijn Excelbestand opent.
Vervolgens zou ik graag een macro willen starten, het Excelbestand weer op laten slaan en sluiten.
Ik kan met een ander component data importeren en exporteren tussen Excel en Grasshopper.
Ik zou graag hulp willen met het schrijven van dit script, dus bij deze mijn hulpvraag!

Ik hoop dat iemand mij kan helpen hiermee.

Met vriendelijke groet,

Patrick Marinus
Technische Universiteit Eindhoven

(in de bijlage heb ik een afbeelding toegevoegd van het VB.NET-component en het script in Grasshopper)
 

Bijlagen

  • VB script.jpg
    VB script.jpg
    89,3 KB · Weergaven: 39
Waar zit het echte probleem? ik ken noch grasshopper noch rhinoceros, maar het aansturen van excel dmv VB.net is redelijk veel informatie over te vinden. (google vb.net excel automation)

Door de specifieke componenten van je vraag is het moeilijk voor anderen te zien waar het precies fout gaat, maar met de kern van je vraag heb je denk ik meer succes.
 
De kern van de vraag is een script in VB.net om een Excelbestand automatisch te openen, macro's te starten en na het draaien van de macro's op te slaan en te sluiten. Met de zoekfunctie op het forum, maar ook via Google kom ik er nog niet uit door mijn geringe ervaring met VB.net. Vandaar mijn hulpvraag hier.
 
Dit voorbeeld komt rechtstreeks van microsoft:

Code:
        Imports Excel = Microsoft.Office.Interop.Excel 
        Dim oExcel As Excel.ApplicationClass
        Dim oBook As Excel.WorkbookClass
        Dim oBooks As Excel.Workbooks

        'Start Excel and open the workbook.
        oExcel = CreateObject("Excel.Application")
        oExcel.Visible = True
        oBooks = oExcel.Workbooks
        oBook = oBooks.Open("c:\book1.xls")

        'Run the macros.
        oExcel.Run ("DoKbTest")
        oExcel.Run("DoKbTestWithParameter", "Hello from VB .NET Client")

        'Clean-up: Close the workbook and quit Excel.
        oBook.Close (False)
        System.Runtime.InteropServices.Marshal.ReleaseComObject (oBook)
        oBook = Nothing
        System.Runtime.InteropServices.Marshal.ReleaseComObject (oBooks)
        oBooks = Nothing
        oExcel.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject (oExcel)
        oExcel = Nothing

Zelf niet getest, maar er is genoeg te vinden zelfs in de help van microsoft. Als je "visible = true" weglaat draait het volledig onzichtbaar op de achtergrond. Ik zou eerst even testen met deze code en zien waar je verder vastloopt
 
Dit is de code welke in het component in Grasshopper zit, hier zit ook het stuk code in wat je me gegeven hebt.

Code:
Option Strict Off
Option Explicit On

'Import SDK and Framework namespaces
Imports Rhino
Imports Rhino.Geometry
Imports Rhino.Collections

Imports Grasshopper
Imports Grasshopper.Kernel
Imports Grasshopper.Kernel.Data
Imports Grasshopper.Kernel.Types

Imports GH_IO
Imports GH_IO.Serialization

Imports System
Imports System.IO
Imports System.Xml
Imports System.Xml.Linq
Imports System.Linq
Imports System.Data
Imports System.Drawing
Imports System.Reflection
Imports System.Collections
Imports System.Windows.Forms
Imports Microsoft.VisualBasic
Imports System.Collections.Generic
Imports System.Runtime.InteropServices



'Code generated by Grasshopper(R) (except for RunScript() content and Additional content)
'Copyright (C) 2013 - Robert McNeel & Associates
<System.Runtime.CompilerServices.CompilerGenerated()> _
Public Class Script_Instance
  Inherits GH_ScriptInstance
  'Implements IGH_ScriptInstance

#Region "Members"
  ''' <summary>List of error messages. Do not modify this list directly.</summary>
  Private __err As New List(Of String)

  ''' <summary>List of print messages. Do not modify this list directly, use the Print() and Reflect() functions instead.</summary>
  Private __out As New List(Of String)

  ''' <summary>Represents the current Rhino document.</summary>
  Private doc As RhinoDoc = RhinoDoc.ActiveDoc

  ''' <summary>Represents the Script component which maintains this script.</summary>
  Public owner As Grasshopper.Kernel.IGH_ActiveObject

  ''' <summary>Represents the number of times that RunScript has been called within this solution.</summary>
  Public runCount As Int32
#End Region

#Region "Utility functions"
  ''' <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  ''' <param name="text">String to print.</param>
  Private Sub Print(ByVal text As String)
    __out.Add(text)
  End Sub

  ''' <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  ''' <param name="format">String format.</param>
  ''' <param name="args">Formatting parameters.</param>
  Private Sub Print(ByVal format As String, ByVal ParamArray args As Object())
    __out.Add(String.Format(format, args))
  End Sub

  ''' <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  ''' <param name="obj">Object instance to parse.</param>
  Private Sub Reflect(ByVal obj As Object)
    __out.Add(GH_ScriptComponentUtilities.ReflectType_VB(obj))
  End Sub

  ''' <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  ''' <param name="obj">Object instance to parse.</param>
  Private Sub Reflect(ByVal obj As Object, ByVal method_name As String)
    __out.Add(GH_ScriptComponentUtilities.ReflectType_VB(obj, method_name))
  End Sub
#End Region

  ''' <summary>
  ''' This procedure contains the user code. Input parameters are provided as ByVal arguments,
  ''' Output parameter are ByRef arguments. You don't have to assign output parameters,
  ''' they will be null by default.
  ''' </summary>
  Private Sub RunScript(ByVal x As Object, ByVal y As Object, ByVal path As Object, ByRef A As Object) 
  Imports Excel = Microsoft.Office.Interop.Excel
  Dim oExcel As Excel.ApplicationClass
  Dim oBook As Excel.WorkbookClass
  Dim oBooks As Excel.Workbooks

  'Start Excel and open the workbook.
  oExcel = CreateObject("Excel.Application")
  oExcel.Visible = True
  oBooks = oExcel.Workbooks
  oBook = oBooks.Open("path")

  'Run the macros.
  oExcel.Run ("DoKbTest")
  oExcel.Run("DoKbTestWithParameter", "Hello from VB .NET Client")

  'Clean-up: Close the workbook and quit Excel.
  oBook.Close (False)
  System.Runtime.InteropServices.Marshal.ReleaseComObject (oBook)
  oBook = Nothing
  System.Runtime.InteropServices.Marshal.ReleaseComObject (oBooks)
  oBooks = Nothing
  oExcel.Quit()
  System.Runtime.InteropServices.Marshal.ReleaseComObject (oExcel)
  oExcel = Nothing
  End Sub 

  '<Custom additional code> 

  '</Custom additional code> 

End Class

Vervolgens krijg ik via de output van het component de volgende foutmelding(en):

Code:
Error: Syntax error. (line 90)
Error: Type 'Excel.ApplicationClass' is not defined. (line 91)
Error: Type 'Excel.WorkbookClass' is not defined. (line 92)
Error: Type 'Excel.Workbooks' is not defined. (line 93)

Tevens even een afbeelding van het component in Grasshopper. Ik maak gebruik van de input "path" om de locatie van het bestand op te geven. Zie bijlage.
 

Bijlagen

  • Grasshopperplot VB.net.png
    Grasshopperplot VB.net.png
    15,4 KB · Weergaven: 25
De errors lijken de excel interop niet te vinden. Mogelijk moet de "imports" bovenaan bij de rest (je hebt imports voor excel nu in de sub gelaten). Bij het aanroepen van de macro moet je daar overigens natuurlijk de juiste macronaam gebruiken

"DoKbTest" is de naam van de voorbeeldmacro van microsoft.
 
Ik snap wat je bedoeld. Zojuist geprobeerd om de excel interop naar boven te verplaatsen bij de andere "imports". Dit stuk van het script kan ik echter niet aanpassen, is beveiligd tegen aanpassingen. Is er wellicht een andere manier om dit probleem te omzeilen? Dat ik naar de juiste macro moet verwijzen begrijp ik, zal dit aanpassen. Voor nu werkt het helaas nog niet.
 
Tja ik ken de beperkingen en mogelijkheden van grasshopper niet. Volgens mij kun je eventueel met "createobject" alsnog wel bij de excel server via COM, maar daar heb ik nu geen voorbeeld van. Is er niet een setting ergens in grasshopper om je "environment" aan te passen oid, zodat je toch aanpassingen kan maken?
 
Ik heb gezocht naar een dergelijke setting in Grasshopper maar deze is er helaas niet. Wellicht dat Excel te benaderen is via een andere manier zoals je beschrijft?
 
Ik heb helaas erg weinig tijd om er naar te kijken, maar als je de fully qualified naam direct gebruikt werkt het dan ook niet?
Code:
Dim oExcel As Microsoft.Office.Interop.Excel.ApplicationClass
Eigenlijk verwacht ik niet dat dit beter gaat, maar je kunt het eens proberen als puur de imports het probleem is.

createobject kun je zo eens testen:

Code:
Dim xlApp As Object
xlApp = CreateObject("Excel.Application")
 
Laatst bewerkt:
Ik heb al het bovenstaande geprobeerd, echter zonder resultaat. Ik kan eventueel wel een ander eigen geschreven VB-script aanroepen via de module in Grasshopper. Wellicht dat een volledig eigen geschreven script wel gaat werken?
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan