Read VBA constant from VSTO add-in? - vba

Is it possible for an Excel VSTO add-in to read a constant from the vba code of a workbook? For example I have two constants stored in a module of all excel workbooks I have created
Public Const APPName As String = "test_app"
Public Const APPVersion As Double = 1.02
What I would like to do is pull these constants from the Application_WorkbookOpen sub of my VSTO add-in. I need this information to determine if the user should be able to open and modify the file, and log usage.

I know this question is quite old but for reference ... i just got the same requirement and solved it using a function which can be called from VSTO (in this example GetAppName) that returns the desired value.
string appName = (string)Application.Run(string.Format("'{0}'!GetAppName", Application.ActiveWorkbook.Name));

Related

Clear cells in multiple sheets from SSIS by VBA

How I can use below VBA coding in SSIS vba. I want to clear cells(data) from multiple sheets from SSIS by VBA coding
sub cod()
ThisWorkbook.Worksheets("Case management details").Range("A2:K10000").clear
ThisWorkbook.Worksheets("interface Timeliness").Range("A2:G20000").clear
ThisWorkbook.Worksheets("Life Events").Range("A2:N10000").clear
End sub
I had the same problem here. If you decided to solve this using SSIS component try with Script Task.
After you create excel steps will be:
Add Script Task on control flow.
Double click on component.
Press 'Edit Script...' button.
Right-click on the project in new visual studio windows (should be something like 'ST_' and some guid) and click on Manage NuGet Packages...
From 'Browse' tab install:
Microsoft.Office.Interop.Excel
Microsoft.CSharp
Into namespaces region add these 2 lines:
using Microsoft.Office.Interop.Excel;
using Microsoft.CSharp.RuntimeBinder;
Copy below code into ScriptMain class:
var appExcel = new Excel.Application();
string filename = #"D:\PathToExcel\ExcelFile.xlsx";
var newBook = appExcel.Workbooks.Open(filename);
var oSheet1 = newBook.Worksheets["Case management details"];
oSheet1.Range("A2", "K10000").Delete();
newBook.Save();
appExcel.Workbooks.Close();
appExcel.Quit();
Close without saving the second visual studio window (where you write script code).
Run the package
Note:
Instead of hardcoded file location, you can replace it with a package variable. In this case 2nd line will be:
string filename = Dts.Variables["User::ExcelFilePath"].Value.ToString();
I tested this package before write answer and everything work perfect!
With this logic, create multiple sheet instance and delete what you want.
If something isn't clear or non-logical write me in a comment and I will make correction.

Need code help on calling a macro from a new VTSO addin for Word

I have created a new addin with a ribbon in MVS. On click of button1 I want to run a macro that is stored in a .dotm file in the Startup folder in Word. The .dotm file is called MyMacros and the macro is titled "TableMacro".
The module name in Word is titled NewMacros and the top rows of the macro in Word are:
Sub TableMacro()
`
` TableMacro
I am sure the macro is started with the code below but even this is guess:
Private Sub Button1_Click_1(sender As Obeject, e As RibbonControlEventArgs) Handles Button1.Click
`code to call TableMacro'
End Sub
I know how to write macros but I have no idea the code needed to trigger the macro stored in the MyMacros.dotm file.
To search all global templates, including the Building Block template, from a VSTO add-in, you can use this:
Dim wApp = Globals.ThisAddIn.Application
Dim i As Integer, Tmplt As Word.Template = Nothing
For i = 1 To wApp.Templates.Count
If wApp.Templates(i).Name = "MyMacros.dotm" Then
Tmplt = wApp.Templates(i)
wApp.Run(Tmplt.Name & "!TableMacro")
End If
Next
The value of performing it this way is you now have an object variable set to a specific global template and you can then get at AutoText, Styles, etc. and of course macros that are stored in that specific global template.
Your VSTO code has a Microsoft.Office.Interop.Word.Application object. Say you're storing that reference in a variable named hostApp, you could do this:
hostApp.Run("TableMacro")
That requires the .dotm file to be the "active" document. If the document isn't active and you have a reference to it (say, theDocument), I think this might work (untested):
hostApp.Run(theDocument.Name & "!TableMacro")
The object VB.NET uses is the same one VBA uses, so if Application.Run "MyMacros!TableMacro" works in VBA, it will work in VB.NET. I'd try to fiddle in VBA first to get the syntax right - you get instant feedback, vs needing to build and launch the host, load the add-in and test the thing with VSTO.
The following Run syntax worked for me from within a VSTO Add-in to run VBA code in a Template loaded as an add-in. It uses the module name plus the macro name.
Keep in mind that Run can only work with public subs...
Globals.ThisAddIn.Application.Run("Module1.TestPublicVarx")

Can a Variable be stored in an Excel File that can not be accessed through Excel

I just discovered that in MS Word it is possible to store a Variable in a MS Word File that can not be accessed through the regular interface when running Microsoft Word.
Sub SetMyVariable()
Dim VARNAME As String
VARNAME = "HiddenVar"
ActiveDocument.Variables.Add VARNAME, "My special info"
End Sub
This gets saved in the XML Schema under word\settings.xml
I have tried using the ThisWorkbook Object in Excel, but it doesn't seem to have a Variable object that can be added like in word.
I want to know if there is something similar in Excel to store information/varialbes that get saved with the file.
PS: the closest thing I can think of (and use in codig) is a hidden named range.
You can try with the CustomXMLParts property of the Workbook which from the link seems a generic feature of Office products and available in Excel. Given you noted that a user would have to manually inspect the XML within the unzipped xlsx files then this seems to map to the Word Variables feature. The code sample just substitutes ThisWorkbook for ActiveDocument:
Option Explicit
Sub TextXMLPart()
Dim objXMLPart As CustomXMLPart
'add
Set objXMLPart = ThisWorkbook.CustomXMLParts.Add("<foo>bar</foo>")
'inspect
For Each objXMLPart In ThisWorkbook.CustomXMLParts
Debug.Print objXMLPart.XML
Next objXMLPart
End Sub
The accepted answer to this question (which focuses on Excel and vsto) states that:
Custom XML parts For an application-level add in, this is my preferred method of storing any application data that needs to be persisted in a saved xls file without ever being visible to the user.

How to access a Word public variable in Excel VBA

I'm trying to automate some report generation where Excel VBA is doing all the work. My employer has a standardized set of templates of which all documents are supposed to be generated from. I need to populate one of these templates from Excel VBA. The Word templates utilize VBA extensively.
This is (some of) my Excel VBA code:
Sub GenerateReport() ' (Tables, InputDataObj)
' code generating the WordApp object (works!)
WordApp.Documents.Add Template:="Brev.dot"
' Getting user information from Utilities.Userinfo macro in Document
Call WordApp.Run("Autoexec") ' generating a public variable
Call WordApp.Run("Utilities.UserInfo")
' more code
End sub
In the Word VBA Autoexec module, a public variable named user is defined and declared. The Userinfo sub from the Utilities module populates user. Both these routines are run without any complaints from VBA. I would then like to be able to access the user variable in my Excel VBA, but I get the following error
Compile Error: Variable not yet created in this context.
How can I access the Word VBA variable in Excel VBA? I thought it more or less was the same?
EDIT: the user variable is a user defined Type with only String attributes. Copying the Word VBA functions that populate the user variable is absolutely doable, just more work than I though was necessary...
In a Word module:
Public Function GetUserVariable() As String '// or whatever data type
GetUserVariable = user
End Function
In an Excel module:
myUser = WordApp.Run("GetUserVariable")
Alternatively, you could be able to replicate the variables value - as it's called user I suspect it is returning some information about a user, or author, of a document. In which case one of the following might be what you're after:
'// Username assigned to the application
MsgBox WordApp.UserName
'// Username defined by the system
MsgBox Environ$("USERNAME")
'// Name of the author of the file specified
MsgBox CreateObject("Shell.Application").Namespace("C:\Users\Documents").GetDetailsOf("MyDocument.doc", 9)
Another option - if you could only add a line of code to the Utilities.UserInfo sub (after setting your public variable):
ActiveDocument.Variables("var_user") = user
Then you could access it easily afterwards in Excel:
Sub GenerateReport() ' (Tables, InputDataObj)
' code generating the WordApp object (works!)
'I am assuming your WordApp object is public, as you don't declare it.
'Capture the new document object
Dim newdoc as Object
set newdoc = WordApp.Documents.Add(Template:="Brev.dot")
' Getting user information from Utilities.Userinfo macro in Document
Call WordApp.Run("Autoexec") ' generating a public variable
Call WordApp.Run("Utilities.UserInfo")
'Get and show the value of "user"
Dim user as String
user = newdoc.Variables("var_user")
msgbox, user
End Sub
This is assuming that useris a string.
EDIT: As it is a requirement to work only on the Excel VBA, I would definely try the approach suggested by Scott and MacroMan - replicating the same functionality of the Word macros in Excel - if possible.
I assume that you've already ruled out the possibility of using an edited copy of the original template, set in a public folder...
For the sake of completness, there is another possibility: actually it is possible to inject VBA code in a Word document without the VBProject Object Model, by "brute force". If you rename a Word document as a .zip file and open it, you will notice a \word\vbaProject.bin file in it. This file contains the VBA project for the document and, in principle, one could add or change VBA code by modifying or replacing it.
I did some tests transplanting code from one document to another by simply copying the vbaProject.bin file, and the concept works. If you are interested in learning more about this file, this topic could be of use.
Notice, however, that to do what you want with such a technique would be somewhat complex (it would involve, for starters, updating zip files from your Excel VBA), and would require a lot of experimentation to mitigate the risk of accidentally corrupting your files. Definetly not recommended if you are looking for an easy and simple solution - but it is possible.

Reading and Parsing Excel in .NET

I have googled, and rummaged through stackoverflow with no luck on the matter.
I have found countless ways to import an entire excel file into a datagridview, but this is not what I want.
Basically, I have an excel file with multiple users (in one column) and a unique ID in another column. I want to only parse specific users and the corresponding unique ID from that row.
How Can I do this?
There are several ways to read the contents of an Excel file. One possibility is to use Excel's object model through the Excel Interop API. Using this approach, you'll interact with Excel using objects:
Imports Microsoft.Office.Interop
Public Class ExcelReader
Public Sub Read(filename As String)
Dim excel As New Excel.Application
Dim book As Excel.Workbook = excel.Workbooks.Open(filename)
Dim sheet As Excel.Worksheet = book.Worksheets("Sheet1")
Dim first_cell_text As String = sheet.Cells(1, 1).Value().ToString
Dim a_number As Integer = sheet.Cells(1, 2).value
End Sub
End Class
You need to add a reference to the Excel interop DLL, which on my machine is located at C:\Program Files (x86)\Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Office.Interop.Excel.dll. I am pretty sure you need to have Excel installed on any machine that runs the app, too.
Documentation for the Excel object model is available here.
Other options include reading an Excel file as if it were a database using ADO.NET, and using third party libraries that can read Excel.