How can assign macro that is in WorkSheet module and has several arguments to a command button for Insert new TableRow in protected Sheet? - vba

I have a Command button in my Worksheet ("Sheet1"), under a Table.
My sheet is protected and I need let user add new rows.
Bellow macro was wrote for do that: (This is in a WorkSheet module)
Sub TblNewLine(Sht As String, Tbl As String, Pass as String, Filtering As Boolean, Pivot As Boolean)
if Nor Pass = vbNullString then
Dim strP as String
strP = InputBox ("Please input Password","Password")
if Not strP = Pass Then
if not strP = vbNullString Then MsgBox "Wrong Password!", vbCritical, "Error!"
Exit Sub
End If
End If
Sheets(Sht).Unprotect
Sheets(Sht).ListObjects(Tbl).ListRows.Add
Sheets(Sht).Protect AllowFiltering:=Filtering, AllowUsingPivotTables:=Pivot
End Sub 'TblNewLine
for example: arguments are:
sht:= "sheet1", Tbl:="PvtReport", Pass:="", Filtering:=True, Pivot:= True
Thus I need assign this macro to prepared command button that is under Table.
And passing arguments with pressing button.
In assign macro form, I cant find above macro in Macro names combo box.
How can I assign above macro and its related arguments to a command button?
Or is there any better solution for Insert new row to protected sheet Table?

Try something like below:
Sub Button1_Click()
Call TblNewLine("Sheet1", "PvtReport", True, True)
End Sub
Sub TblNewLine(Sht As String, Tbl As String, Filtering As Boolean, Pivot As Boolean)
Sheets(Sht).Unprotect
Sheets(Sht).ListObjects(Tbl).ListRows.Add
Sheets(Sht).Protect AllowFiltering:=Filtering, AllowUsingPivotTables:=Pivot
End Sub
EDIT :
See image for reference

With great thanks from Mrig's guidance; For more explanation I Present whats i reached, as an answer:
there is a way for passing arguments with Command button, that I read in QA Collective's Answer for a related question.
At first i encountered 'cannot run Macro' error from Microsoft Excel, but when I closed and open workbooks document, looked Macro name field in Assign Macro was changed as bellow and my subroutine called truly by passing constants with click on button.
'FileName.xlsm'!'TblNewLine "SheetName", "tblReminder","",True,False'
Please not that ' character for enclose subroutine name and arguments list string, both in twisted '.
in above example, my sub needs 5 arguments so they pass with each command button that want calling this sub.
The point about assign macro that has no arguments, and there is in Worksheet module is there are listed below of Asign Macro combo list and not in order of subroutines are in other modules.
if subroutine macros has argument, there not listed in Asign Macro and should input them in related field as above example i explained.

Related

VBA Word Macro to Allow User to Select and Copy Text Multiple Times

I am working on a VBA script with Microsoft Word that allows the user to select text that will be be copied to the clipboard so that it can exported to an Excel file. The user will make a number of selections and finally indicate he/she is done when the contents of the clipboard will be copied to a template Excel file.
There are two forms: the first (UserForm1 in the code below) queries the user for the Word filename. The filename variable is passed to the second form. The second form (frmModeLessForInput) is a modeless form. The behavior I need is that program control goes to the second form with two buttons "Continue" and "Done".
The user is allowed to navigate the document and place the cursor anywhere in the document. Then when "Continue" is pressed the form will call a subroutine (Highlight_Sentence) to copy the selected text to a "clipboard" variable. When "Done" is pressed control will be passed to called main module which will then copy the clipboard to the Excel file.
Below is the code. I have noted with comments where I am trouble with the code. One problem is the variables defined as Public in the ThisDocument module are not defined in the userforms and their subroutines.
The second problem is in the main module that the frmModelessForInput is supposed to be displayed and control is not supposed to be transferred to next statement {MsgBox "Sentences will now be copied to Excel file"....this is where I will put the code to copy the clipboard to the Excel file.} but the message appears before the frmModelessForInput form is run...thus the clipboard will be empty.
The third problem is that in frmModelessForInput form the statement str_clipboard = str_clipboard + str_clipboard_line is not working. Each time the "Continue" button is pushed str_clipboard loses it previous contents.
Any assistance in resolving these problems is appreciated. As VBA programming is a sideline for me I am still learning.
Note this an updated question Pause VBA Word macro, allow user to make a selection, and restart where it left off adding some more detail on the requirement and the sample code.
MAIN MODULE:
Option Explicit
Public str_clipboard As String
Public txt_active_document As String
Public i_how_many_sentences As Integer
Private Sub Test_master_macro()
UserForm1.Show
i_how_many_sentences = 0
Call DisplayModeless
MsgBox "Sentences will now be copied to Excel file" 'Problem: this msg displays before the frmModelessForInput is displayed
End Sub
Sub DisplayModeless()
Dim frm As frmModelessForInput
Set frm = New frmModelessForInput
With frmModelessForInput
.str_word_doc_filename = txt_active_document
.str_no_copied = "0"
.Show False
End With
Set frm = Nothing
End Sub
USERFORM1: form has field for user entering the document filename to user (str_filename) and a command button to close form (cmd_start_selecting_text)
Private Sub cmd_start_selecting_text_Click()
'User enters filename on form for use in frmModelessForInput subroutine
txt_active_document = UserForm1.str_filename 'Problem: VBA reports txt_active_document as undefined even though it is a Public variable
Unload Me
End Sub
FRMMODELESSFORINPUT: Form displays filename of Word file entered in UserForm1 and how many sentences have been copied to the clipboard
Option Explicit
Private Sub cmdContinue_Click()
Dim str_clipboard, str_clipboard_line As String
Call Highlight_Sentence(str_clipboard_line)
i_how_many_sentences = i_how_many_sentences + 1 'Problem: VBA reports i_how_many_sentences as undefined even though it is a Public variable
frmModelessForInput.str_no_copied = i_how_many_sentences 'Same Problem
str_clipboard = str_clipboard + str_clipboard_line 'Problem: each time I select a new text/sentence str_clipboard does not contain the contents of the previous selection
End Sub
Private Sub cmdDone_Click()
Me.Hide
End Sub
Private Sub UserForm_Activate()
'Position the form near the top-left of the window
'So that the user can work with the document
Me.Top = Application.ActiveWindow.Top + 15
Me.Left = Application.ActiveWindow.Left + 15
End Sub
Private Sub Highlight_Sentence(clipboard As String)
'This sub extends the selection to the entire sentence and copies the selection, the page number on which the selection is contained and the filename to the clipboard variable
Dim txt_sentence, txt_page_no As String
With Selection
' Collapse current selection.
.Collapse
' Expand selection to current sentence.
.Expand Unit:=wdSentence
End With
txt_sentence = Selection.Text
txt_page_no = Selection.Information(wdActiveEndPageNumber)
clipboard = txt_active_document & vbTab & txt_page_no & vbTab & txt_sentence & vbCrLf 'Problem: VBA reports txt_active_document as undefined even though it is a Public variable
End Sub
From what you stated you are running this from the ThisDocument Class Module and unless you fully qualify your references to those Public variables with the Class Name that is why you cannot access them from the UserForms Class Modules.
If you are going to leave your "Main Module" code in the ThisDocument Class Module then whenever you reference those Public variable you need to add ThisDocument.str_clipboard to the command.
I recommend however, to place your Main Module in a general Module such as NewModule and if you need to run it at a Document_Open event that you put a call to the Main Module and its Public variables in the Private Sub Document_Open event of the ThisDocument Class Module.
Your Msgbox is appearing at the wrong time because you are displaying a modeless user form, which means the VBA script thread continues to run after the UserForm is displayed. Move the Msgbox to the UserForm_Activate routine of the second UserForm you are displaying or move it to the Click_Done routine of the first UserForm before you Hide or Unload it.
Finally, you are not really using the Clipboard and using that term makes your code confusing in my opinion. I think you should rename it. Your code also appears to just be building one continuous string of text. Is that really what you want to do? Or, do you really mean to capture each selected text string and ultimately place each into separate cells within an Excel Worksheet? If that is the case, use an Array for the separate text strings.

Get editbox value on "Return in Excel ribbon with VBA

My first question here.
I'm trying to add a custom search field in Excel ribbon. My problem with the usual research : its default range is "this worksheet" whereas I'd want the whole Workbook (or even other known workbooks).
So I created an editbox in the ribbon. I use "onChange" to validate my input and trigger my custom research sub.
But I'd prefer it to be triggered only when I press "Enter" key on my keyboard, or give focus to another ribbon button (a button "search" wich would trigger the research sub with my editbox value, and wich would be activated when pressing Return while focus is still on editbox.
My other problem is that leaving the field also triggers the sub (onChange is activated when leaving) ; it doesn't trigger the event if editbox has not been changed ; and I can't catch the "Enter pressed" action.
Are there ways to solve what I'm trying to do ?
If not, is there a way to call the native search function with "workbook" range as default range, instead of "this worksheet"?
Thank you for help.
JP
What I did in the end (I just need to scan the first column):
an editbox in the ribbon wich updates a variable whose range is my module.
a "Go" button in the ribbon, wich launches the research of the string stored in the variable.
The code I used (for sure that's simple, but may help other beginners such as me):
Private nomPatientRecherche As String
Public Sub RecherchePatient(control As IRibbonControl)
Dim feuille As Worksheet, zone As Range, cellule As Range
For Each feuille In ThisWorkbook.Worksheets
feuille.Activate
Set zone = feuille.Range("A2:A" & ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row)
For Each cellule In zone
If Not cellule.Find(nomPatientRecherche) Is Nothing Then
cellule.Activate
If Not MsgBox("Continuer ?", vbOKCancel, "Continuer ?") = vbOK Then
Exit Sub
End If
End If
Next cellule
Next feuille
End Sub
Public Sub DefineNomPatientRecherche(control As IRibbonControl, nom As String)
nomPatientRecherche = nom
End Sub
Thanks again #Rory for your help

Insert text string through other macro with Excel VBA

I'm having an issue and dont know if this is possible to be done.
I need to insert a string variable through another macro that is protected and can't access the VBA code.
At my code, I intend to send a string when call the protected macro (with application.run "macroname"). This protected macro prompts a selection window to select a file. I pretend to automatically insert at macro's prompt my string and send "ENTER" command to open the desire file.
Is this possible to be done?
If I understood you correctly, this is what you are looking for:
1) Locked workbook (VBA module is protected) contains e.g. the following macro:
Public Sub Test(sInput As String)
ActiveCell.Value = sInput
MsgBox sInput
End Sub
What you are trying to do, is to call this Test macro, but you don't know how to pass parameter (correct me if I got this wrong).
This is how you do it:
Sub RunProtectedMacro()
Dim vResult As Variant
vResult = Application.Run("'" & LockedWorkbook.Name & "'!Test", "some string argument")
End Sub

VBA (excel) - How do I feed UserForm Textbox to function?

I have a sub that works to clear values from a userform textbox but I tried to convert it to a function so I can use it with multiple userforms.
Here's my userForm Code (the command button code)
Private Sub pdclear_Click()
Dim passform As UserForm
Set passform = NoteEntryForm1
Dim inputtext As TextBox
Set inputtext = frmBigInputBox
Call clear(passform, inputtext)
End Sub
Here is my function
Function clear(passform As UserForm, inputbox As TextBox)
passform.inputbox.Value = vbNullString
End Function
Trying to execute returns "Type missmatch" error.
I set it as a userform and a textbox. What am I doing wrong?
thank you :)
You define the function to have two parameters. Then in the function you concatenate the parameters as if one is a member of the other. That will give an error. To address the input box on the user form, use:
Function clear(passform As UserForm, inputbox As TextBox)
passform.Controls(inputbox.Name).Value = vbNullString
End Function
or even more simple:
Function clear(inputbox As TextBox)
inputbox.Value = vbNullString
End Function
(I have not been able to test this as I have no test module with forms in Excel.)
The error Type Mismatch is very clear, you're setting into a variable declared as TextBox something that, apparently, is not a TextBox.
My suggestions:
Check the type using the function TypeName(object), and make sure it's actually a TextBox:
Debug.Print TypeName(frmBigInputbox)
If the TextBox is a child of the passform, then tell this to VBA :
Set inputtext = passform.frmBigInputBox

Debugging "Search for Name" Code in VBA

I have solid experience in C++ but am still getting used to the syntax of VBA and I think that's what's tripping me up in my code.
What I'm trying to do is have a button that asks the user for a name. If the name entered is in column B, then tell the user the name was found and select where it is (no problem with this). If the name is not found, then ask if the user wants to try another name (no problem with this, either).
Where I'm having trouble is with the "Cancel" buttons. At any time, I want the user to be able to hit "Cancel" and immediately stop the loop, but stay in the sub because I'll be adding to this later.
Here's the code:
Dim inputName As String
Dim row As Integer
Dim i As Integer
Dim tryAgainResponse As Integer
tryAgainResponse = vbOK
'Ask user for name they would like to replace'
inputName = InputBox("What is the name of the person you would like to find? (First Last)")
'Find the row that the name is located and tell the user where it is'
Do While tryAgainResponse = vbOK
For i = 1 To 1000
If Cells(i, 2).Value = inputName Then
MsgBox ("Found the name! It's located at cell B" & i & ".")
ActiveSheet.Cells(i, 2).Select
tryAgainResponse = 0
Exit Do
End If
Next i
tryAgainResponse = MsgBox("We didn't find the name you were looking for. Please try again.", vbOKCancel)
If tryAgainResponse = vbCancel Then
Exit Do
End If
inputName = InputBox("What is the name of the person you would like to find? (First Last)")
Loop
I've tried plenty of things, but the main error is when you hit cancel for the first MsgBox, it tells you the name was found in the first blank square.
Any help or suggestions would be greatly appreciated! This is my first VBA program, so it's not the prettiest, but it's definitely a lot of fun. Thanks!
I'm not sure if I'm understanding what you're asking for, and I can't comment for clarification, but I think your hang up is that when you click cancel on the INPUT box, your input box is returning a blank string, and the rest of your code is then finding a blank cell.
Use the Application.Input Method, declare your input string as a variant, and test if it is false. If it is, use an Exit Sub to exit the macro. You could also test if your input string = "" and then exit the macro if true with the code you have.
From MrExcel
There are 2 versions of InputBox in VBA.
The InputBox Function is called without an object qualifiier and returns the contents of the text box or a zero-length string ("") if the user clicks Cancel.
The InputBox Method is a member of the Application object, so it is called by using Application.InputBox. It returns the contents of the text box or False if the user clicks Cancel. It is more versatile than the InputBox Function because it has a Type argument which specifies the return data type.
The function InputBox() will return an empty string if cancelled. The empty string will compare equal to the first cell that is empty.
Here's the doc of the function: http://msdn.microsoft.com/en-us/library/6z0ak68w(v=vs.90).aspx