Import or Add code to an add-in dynamically - vba

I am working on a project where I have created a PowerPoint addin. The concept is this will only contain an user form, with a list box. Based on the user selection other modules (bas files) will be added or imported to the presentation and the code will be executed.
I don't want to include all the modules in the add in as depending upon the requirement I can do the modification and then can store in a shared folder. So every time user uses the addin they can have the updated version. So I don't have to re circulate the addin with every change.
I have a blank module where i import the code from a text file (code from bas file saved as text) and it runs.
I can import the bas files, also using inserFrom file option I can import code from a text file, but problem is it's always getting added to the current presentation code window. But I want to add the code to the addin code pane.
I have a blank module in the addin called "tempCode", where I want to update the imported code, but I am not able to do so.
It works fine when I am editing the addin as a ppt, but when I convert ppt to an addin the concept is not working.
Any ideas how I can add the code to the addin code pane rather adding to the active ppt.
Code details:
I have a user form, with a list box.
It has 3 items.
Option 1
Option 2
Option 3
If user selects any option, let's say option 2, the code for option 2 will be imported from a text file to the working module.
And a command button to run the selected.
Name of working module is “Mod_Working”
Name of text file is “C:\Code\Option2.txt”
Below is the code I am using:
Sub ImportSelected()
With ActivePresentation.VBProject.VBComponents(“Mod_Working”).CodeModule
.DeleteLines 1, .CountOfLines 'it deletes any existing code
.AddFromFile “C:\Code\Option2.txt”
End With
End Sub
Code in text file:
Sub Test
Msgbox “You selected Opt 2”
End sub
Code of Command Button:
Private Sub Cmd_run_Click()
Application.Run “Mod_Working.Test”
End Sub
This works in ppt mode but not when converted to addin.

Why not do this:
- In the shared folder, mark the add-in file as read-only (right-click, properties). This prevents the file being in-use when people are using the add-in (at least it works that way in Excel)
- When you have an update, simply replace the add-in and set it to read-only again.
Alternatively, check out: www.jkp-ads.com/articles/updateanaddin.asp

Related

vba macro list box not letting editing some macros

I have an Excel project with a lot of macros.
What I want is assign macros to buttons in the ribbons.
For that I created macros like:
Sub R10_parallel_device()
help.helpON ("parallel_device ")
Call sub_novelty_claims("parallel_device")
End Sub
So the three conditions are met:
a) the macro SUB R10_parallel_device() do not accept parameters
b) it is not private
c) It is not hide
when I go to the list of macros I see all the list of macros named Rnn but all THE BUTTONS ARE GREY OUT EXCEPTFOR CREATE.
Now if I click in that sub for instance SUB R10_parallel_device() I can not edit it and if I click "create" excel sends me to a new created module where
Sub R10_parallel_device()
End Sub
appears.
&
When I go to file/options/ribbon if I want to add that macro to a button it is listed and it is possible to assigne the macro to a button but it would not run, giving the error that such a macro is not found.
NOTE: I checked which macro are listed thisworkbook/all/ etc.
note2: this did not help me. this neither
thx
Confirmed it's the macro names - go to Developer -> View Code (or type Alt + f11), then select the module with your code in it and rename them. For whatever reason it's that R# syntax:

Disable File>Share in Excel with VBA

I need a way to disable the ability for a user to go to (or use) the menu File > Share
I have similar for other save commands like below but need something for this feature as well
Application.CommandBars("Worksheet Menu Bar").Controls("File").Controls("Save As...").Enabled = False
Application.CommandBars("Worksheet Menu Bar").Controls("File").Controls("Save").Enabled = False
I have tried:
Application.CommandBars("Worksheet Menu Bar").Controls("File").Controls("Share").Enabled = False
to no avail
My aim is to stop users saving copies of this file (Hosted on a server), I fully understand Excel isn't meant to be secure and there is always a way to do this but want to make it as hard as I can for the average Joe
Regards
You could use a for each loop to extract the available commands:
' Iterate available commands from the file command bar.
Sub PrintAllCommandBarControlNames()
Dim cbControl As CommandBarControl
For Each cbControl In Application.CommandBars("Worksheet Menu Bar").Controls("File").Controls
Debug.Print cbControl.Caption
Next
End Sub
Run on Excel 2010, I couldn't find a share option. Might just be my system. The above returned:
&New...
&Open...
&Close
&Save
Save &As...
Single Web Page (*.mht)
Save &Workspace...
File Searc&h...
Per&mission...
Per&mission
Ch&eck Out
Ch&eck In...
Ve&rsion History...
We&b Page Preview
Page Set&up...
Prin&t Area
Print Pre&view
&Print...
Sen&d To
Propert&ies
&Recent File Name Goes Here
&Recent File Name Goes Here
Sign ou&t
E&xit Excel
The 'backstage' menu (that you get when you click top left File menu) is effectively part of the Ribbon, and not a Command Bar. If you tried disabling Save for instance, using your example, you'll find they don't work on 2010/2013 etc.
There is this answer which tells you how to manipulate those menu items in the ribbon: Remove "Save & Send" from File menu in Excel 2010 using custom XML and one of the items is called TabShare.

Assign Shortcut keys within the VBE Window

From the Excel Window, I can assign a shortcut key to my macro by:
going to the Developer tab
touching the Macros button
touching Options... in the resulting Dialog Box
Can I assign this from within the VBE Window, using the VBE menu bar instead??
The Application.OnKey approach keeps the shortcut separate from the procedure (which makes maintenance difficult), and you might end up with conflicts - particularly if you've assigned keys using the Macros dialog and the Application.OnKey property. And, of course, you need the SetShortCutKeys code to run on workbook_open, which might not always run.
Fortunately, it is possible to assign the shortcut key in VBA, and within the procedure itself, but you'll need to export the module, edit the text file, and then reimport. Unfortunately, while VBA does maintain the code, the shortcut keys only seem to work in Excel. Perhaps it's a feature of VBA that the host application can optionally support.
Let's say you have the following VBA in a standard module:
Option Explicit
Public Sub Bar()
MsgBox "Bar"
End Sub
If you use the Macros dialog in Excel, and choose a shortcut key for the Bar macro to Ctrl+Shift+T, and then Export the module to a text file, you'll find the module source is:
Attribute VB_Name = "Module1"
Option Explicit
Sub Bar()
Attribute Bar.VB_ProcData.VB_Invoke_Func = "T\n14"
MsgBox "Bar"
End Sub
Notice the Attribute Bar.VB_ProcData.VB_Invoke_Func = "T\n14" attribute, which wasn't visible in the VBIDE, but is persisted by VBA in the underlying source. The T in T\n14 is a case-sensitive key (which implies a Shift), and I think the \n14 must refer to the Ctrl key. By following the VB Attribute naming pattern and syntax, and including similar lines in your other procedures, you can assign shortcut keys in other procedures using the text editor, and then, when you're done, you can import the modified module back into the VBA project.
Note that once you import the modified module, you'll no longer be able to see the attribute lines, and you'll need to take care not to change the name or number of parameters in the procedure, as the VBIDE might delete the underlying attribute without warning you.
Alternatively, if you want to do it using VBA you can do something like:
Sub SetShortcutKeys()
With Application
.OnKey Key:="^+K", Procedure:="YourMacroGoesHere"
End With
End Sub

Disable running macros from the "View Macro" screen until VBA project password is entered?

So first, when one clicks on the "View Macro" button, this pops up:
What I want to know is, is there some code that I can run on workbook open (and then "unrun" on workbook close) that grays out that run button (like the others underneath it are) ONLY until the password is entered in the VBA project (using Alt+F11 to open the editor)?
I don't want the users to be able to run any of these subs manually.
If you declare the sub so that it needs input, even optional input it will not show in the list either.
sub Test(optional a as string)
Declare the subs as private and they won't show up in the Alt+F8 dialog box.
Declare them as public (the default) and they will.
You can use vba to edit the vba code of another module.
Is it possible in Excel VBA to change the source code of Module in another Module
You can change one line or search through the lines and comment/uncomment whole blocks of code. Capturing the event when vba is unlocked may be the hard part. You may have to run a sub that does this after unlocking vba.
I think you have the wrong approach to this and it would be better to structure your code more properly.
The first two on that sheet are called from other macros that are run with buttons on my main worksheet.
OK. So attach these to a form control/button, and use Bigtree's suggestion to include an optional argument in these subs. They will not display in the Macros menu. YOU can run them at least three different ways:
either from the VBE by finding the procedure and pressing F5, or
by entering the name of the procedure in the Immediate window in the VBE, or
by pressing the buttons you have provided.
The middle two are called when the sheet opens and closes
Sounds like this should be a private subroutine (or, use the method above from Bigtree) and CALL these from the one or more of the appropriate event handlers (at the worksheet level perhaps: Worksheet_Activate, Worksheet_Deactivate; or at the workbook level SheetActivate and SheetDeactivate depending on your needs)
You can always run the procedure manually from the Immediate window in VBE, or by manually invoking the event procedure, etc.
and the last two I manually call when I want to edit my main sheet
Again, call from the Immediate window or manually from the VBE. You only have 6 subroutines here, it can't be that difficult to locate the ones you frequently need. Put them in a new module and organize your modules so you know where these are.
Alternatively, put some boolean in the subroutine like:
Sub SheetLock()
If Not Environ("username") = "YOUR_USERNAME" Then Exit Sub
'other code to do stuff is below...
End Sub
UPDATE FROM COMMENTS
The Immediate Window is like a console/command line, it is where the result of your Debug.Print statements would appear, etc. It is very handy for debugging and evaluating expressions.
There are several ways you could invoke the subroutine depending on whether it is public/private, including
Application.Run "MacroName" or simply MacroName if public
Application.Run "ModuleName.MacroName" or Call ModuleName.MacroName if private
I did not want to use a private sub,
I used the shape name to determine if from a button
On Error GoTo noshapeselected
shapeis = ActiveSheet.Shapes(Application.Caller).Name
' I manually set the shape name in the page layout tab selection pane
' below I test for the desired button
If shapeis = "your button name" then
goto oktogo
else
goto noshapeselected
endif
noshapeselected:
msgbox ("must run from a button")
goto theendsub
oktogo: 'continue if desired shape was selected
theendsub: 'a button was not pushed
For those macros without buttons, but called by another macro,
set a variable to 'OK' to run a macro, then the called macro tests for 'OK' ('OK' means initiated by another macro 'NOK' means not initiated by another macro)

Open multiple copies of word form?

I'm fair at Access vba but Word is a new dialect for me.
I work for a hospital that has an Electronic Medical Record (EMR). We need a specific format and structure for the Nurse’s Clinical Progress Notes that can’t be created and enforced in the EMR. I created a Word vba UserForm, "frmProgNote" attached to a document "ProgNote.doc". FrmProgNote" has textboxes that create the structure we need for documentation and there is a command button that when clicked sends the info from the form to bookmarks in ProgNote.doc and copies all text from the document, including the newly inserted text onto the clipboard. The user then pastes it into the EMR. This all works great (believe it or not) but now they want to have multiple copies of frmProgNote open at the same time so they can move between several patients at once.
I’ve worked on this for 2 days and just can’t get it. I found I could not open multiple instances of Word and have the same form open in more than one. I copied the document and form so now have ProgNote1.doc with frmProgNote1 and ProgNote2.doc with frmProgNote2. I can get both to open BUT if I open frmProgNote1 then open frmProgNote2 the only data I can copy comes from frmProgNote2; the copy button doesn’t copy anything from the first form. I can click on frm1 and get it to take new data but the copy button doesn’t work anymore. Any suggestions? Thanks so much.
The following code gives the basis for creating a new instance of a UserForm.
Private frmNewInstance As Object
Private Sub CommandButton1_Click()
Set frmNewInstance = UserForms.Add(Me.Name)
frmNewInstance.Show
End Sub
Private Sub UserForm_Terminate()
Set frmNewInstance = Nothing
End Sub
It is necessary to control the object-reference, setting it to Nothing when the form instance is closed.
Note that this process is not as robust or reliable as it would be in, for example, VB.NET or C#. In particular, it is more difficult to distinguish between the different instances of the form.
One approach to consider is to use the Tag property of the form:
frmNewInstance.Tag = "OtherOne"
frmNewInstance.Show