Excel: Fixed Button Position - vba

Needing some help attaching an Excel/VBA button on an Excel sheet. I need it to stay in the same position on the screen regardless of how I scroll or zoom. Preferably, I need this on the bottom left or right of the screen.
I have tried adding a button. Then, I right clicked on the button. Clicked on Format Controls -> Properties -> selected Don't Move or Size With Cells. Am I missing something that's making this not work?
Thanks!

I know this post is old, but here's to anyone it could be useful. The VisibleRange property of ActiveWindow can solve this problem. Use something like this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With ActiveSheet.OLEObjects("MY_BUTTON'S_NAME")
.Top = ActiveWindow.VisibleRange.Top + ActiveWindow.VisibleRange.Height - 5
.Left = ActiveWindow.VisibleRange.Left + ActiveWindow.VisibleRange.Width - .Width - 5
End With
End Sub

Here is the idea that I put across the comment earlier today :) Typically we can get a Floating User Form by setting the Modal property of the form to be 0 which is indeed a Modeless state.
Basic Points to consider:
Look & Feel of the form to make it look like a Button (Not show title bar/Not Resizable/
Hidden Close Button etc)
Setting the position of the Button
Which Event should trigger the form-button (WorkBook Open)
What would you do with Form Initialize Event
Whcih Events should keep it stick to the same position alive
Further Points to consider:
You might only want to keep this button vissible for the workbook you are working, and if you open another instance of a workbook, do you still want to keep the button
If you minimize the Excel Window instance, how do you plan to manage the state of the button and keep it visible
Post about keep displaying a form even the workbook is minimized.
One other great reference I happend to see, (little bit technical) but worth the shot - at least to get to know the certain properties/methods that you could make use: Extending VBA User Form Control.
The article include the following info, and please note the last line as well :)
They give you access to capabilities that are not available from VBA or from the objects (UserForms, Workbooks, etc.,) that make up a VBA Project. When you call an API, you are bypassing VBA and calling directly upon Windows. This means that you do not get the safety mechanisms such as type checking that VBA normally provides. If you pass an invalid value to an API or (a very common mistake) use a ByRef parameter instead of a ByVal parameter, you will most likely completely and immediately crash Excel and you will lose all your unsaved work. I recommend that until you are confident that your API calls are solid you save your work before calling an API function.

Add new Row on the beginning of your WorkSheet and set your button on it, then:
Freeze Top Row

Right click → properties → placement → change to 3.

Related

Auto-updatable links

Is there a way to apply "auto-updatable" style for hyperlink?
I believe, this question is not trivial.
When you normally click on hyperlink, it will change it's color to violet. Next, if you save, close, and then reopen the document, the link will be updated back to blue. This is default behaviour of Word, and there is no need to use any macros for it.
I'm trying to replicate this behaviour with VBA. Here is the code:
Sub Test1()
Selection.Range.Hyperlinks(1).Range.Fields(1).Result.Style = Word.WdBuiltinStyle.wdStyleHyperlinkFollowed
End Sub
To make it work, simply put caret into the link, run macro, and see the results:
This works fine, except such visited links will not be auto-updated after you save, close, and then reopen the document. See the difference in the picture below. The link "Google" was opened normally, using the mouse Ctrl-click; the link "StackOverflow" was opened using the macro:
As I already said, I want to make my VBA-opened links (StackOverflow) auto-updatable as well (as Google).
Yes, I understand, there is a workaround - simply create another macro, which will be started every time the document opened and change all violet hyperlinks back to blue. However, this is just workaround, and I don't like it. Using it, we use conversion from "permanent violet" to "permanent blue", instead of using "temporary violet" (that's mean, auto-updatable without any additional efforts).
Hope everything is clear. Thanks in advance.
Update (was added after several answers were already posted).
Yes, I understand, this will work:
Sub Test1()
On Error Resume Next 'To avoid an error in case if the link isn't reachable
Selection.Hyperlinks(1).Follow
End Sub
But I want just simulate following, without really opening the link in the browser. That's why, I can't use Selection.Hyperlinks(1).Follow.
you need to remove the line, the link will change once followed and change back once the doc is reopened.
Selection.Range.Hyperlinks(1).Range.Fields(1).Result.Style = Word.WdBuiltinStyle.wdStyleHyperlinkFollowed
this does it for me
Sub resetHyperlinks()
Dim hLink As Hyperlink
For Each hLink In ActiveDocument.Hyperlinks
hLink.Address = hLink.Address ' this works
' hLink.ScreenTip = hLink.ScreenTip ' this works also
Next hLink
End Sub
You don't need to change the style with code to make the link purple. Just use the Follow method. This will click the link and turn it purple and then it will be reset to blue upon opening the document again.
Sub Test1()
Selection.Range.Hyperlinks(1).Follow
End Sub
You can reset link styles with VBA code that runs at startup, i.e. is a part of Document_Open() routine in ThisDocument VBA module.
The Hyperlink class doesn't have any .Visited property or anything relevant (i.e. you cannot even see if it was visited), so there's no other way beside .Follow() that also opens the link as it should.
You're basically trying to falsify the information that the document provides about its state: make a link appear visited when it actually wasn't.
The fact that the class doesn't even provide a property means that Word's designers do not consider the visited status a part of the editor's functionality (i.e. it effectively doesn't exist as far as the program's job is concerned).
This evidence suggests that Word doesn't, and is not designed to, have any specialized facility to switch link status other than .Follow(). Which means, any way that you find that happens to have the desired effect in bound to be what you're calling a "workaround".
The "temporary" color of a followed hyperlink is an embedded (and not directly accessible) feature of the built-in Hyperlink character style. It is not exposed through the normal UI's Style tools, nor through the object model.
You can readily compare all formatting between two selections using the Reveal Formatting pane (Shift+F1) in the document window in Word.
If you compare a normally followed hyperlink with a hyperlink affected by your snippet, you'll see that the followed hyperlink still has the Hyperlink style, while your simulated follow has changed the style of the second hyperlink.
If you compare a never-followed hyperlink and a normally followed hyperink, Word identifies their formatting as exactly the same. Word does not acknowledge that any aspect of formatting (style, font color, etc.) has changed.
It seems likely that the Word.WdBuiltinStyle.wdStyleHyperlinkFollowed you are using exists explicitly to address this gap (which is somewhat disappointing).
I recommend using your existing approach, and then reverting the style in a procedure triggered by the Before Save and Before Close events of the document. Using those events will prevent the followed style from saving at all, and so avoid issues caused by someone opening the document without enabling macros.
Option Explicit
Sub test()
Dim HL As Hyperlink
For Each HL In Sheet1.Hyperlinks
HL.Range.Style.Font.Color = vbBlue
Next
End Sub
Can't you simply make it any colour you want without invoking it. As others have stated above whatever you you I think will be a work around as it's not an intended function.

Form Option Button Reset Macro

I am looking for a simple macro I could activate with a form control button that would clear all of the form control option buttons on my sheet.
I have lists of options for industrial part specifications, of which only one may be selected per section. However, once one is selected, the form control option button stays filled in. I previously circumvented this by using checkboxes, where if you click the box again it will remove the check mark. However once I learned that I was to create the form in such a way that only one option could be selected per section, (for ease of use in case a less computer minded person were to use it) it became clear that option buttons were the right way to go.
So I need a simple macro that I can activate with a button that will clear these option buttons all to blank, as if none were selected. I have looked and tried some strings of code, but none have worked so far. Perhaps I am missing something obvious or looking for the wrong thing, but I dont think I am.
I have checked the following pages and tried their code:
http://www.mrexcel.com/forum/excel-questions/689865-how-clear-all-checkboxes-option-buttons-list-boxes-form-3.html
Re-setting all option buttons at once
http://www.excel-easy.com/vba/examples/option-buttons.html
I feel like this should be simple. A VBA macro code that will reset the FORM CONTROL Option Buttons to blank (which I believe is the false state?). No need to worry about having specific ranges to clear; one button to reset the sheet will do perfectly.
Thanks in advance for any help.
Cycle through the Shapes collection:
Sub Reset()
For Each vCtrl In ActiveSheet.Shapes
vCtrl.DrawingObject.Value = False
Next
End Sub

vb.net getsettings

I need a form width a checkbox "Don't show this again" for my winform,
but how can i make this so when my Form1 loads it checks the state of the checkbox using the getsettings option?
How can is save the checkbox state to the registery? and how do i get the state?
If Form2.Checkbox.checked = Getsettings() Then
Form2.showdialog
Else
Goto Skip
End IF
Skip:
Windows Forms has built-in support for that, you don't need to write any code. Select your check box. In the Properties window, scroll to the top on expand the "ApplicationSettings" node. Click on "Checked" and drop-down the combobox. Click New. Set the Name property to something meaningful.
Done. Your check box will always restore with the last selection that the user selected. Don't call Show() when it is turned on, dispose the form right away.
The main crux of the question is "how do I read and write value to and from the registry."
See here for a great overview complete with code.
You're beginner so here are a few tips on your code sample:
Name your objects more verbosely. Form2 will mean nothing to you a few hours from now.
Do not use Goto. Just don't. Please. You either show the dialog or you don't. The whole Else block with the Goto in it is just not necessary.
Few more things you'll need to do to get this working:
Handle the CheckBox checked event and write either a 1 or 0 (or T or F) to a registry value
Read that registry value in your GetSettings method
You might want to pass a parameter to GetSettings that specifies exactly which setting you need because you'll probably want to reuse that method for other settings as well

Programmatically set "Select objects" cursor in Excel

I'm struggling to find out how to programmatically enable the "Select objects" cursor type. I checked the object browser and expected to find a property like Application.CursorType or Application.DrawingMode.
Changing the cursor type isn't picked up in the macro recorder and I must be searching for the wrong terms as I can't find information about this anywhere.
Edit: I should've made it clear I'm not talking about the cursor appearance that can be set via Application.Cursor. Rather, I want to set the cursor into the same mode as can be set via the GUI by clicking the "Select objects" icon on the Drawing toolbar. This is the cursor that only allows selection of shapes and ignores cells, text and the formula bar.
Actually, I never knew the correct name for this cursor mode until I checked the tooltip to write this update, perhaps that'll help.
I don't quite follow why you want to do this, but you can toggle the "Select Objects" drawing mode programmatically by executing the built-in CommandBar control:
Call CommandBars("Drawing").Controls("Select Objects").Execute
And you can determine the current mode by checking its state:
If CommandBars("Drawing").Controls("Select Objects").State Then
Call Debug.Print("Select Object mode is on")
End If
Good luck!
I'm a little 'late to the party' on this one but here is the answer to 'why he wants to do this' as well as 'what he wants to do'.
'Turn ON 'Select Objects' option during initial display. While ON, cell input is prevented.
If CommandBars("Drawing").Controls("Select Objects").State = False Then
CommandBars("Drawing").Controls("Select Objects").Execute
End If
I use this in a simple timer application which has one command button and two check boxes on the 'ActiveSheet' display. By turning ON 'Select Objects', I limit the cursor input targets to these three items. Cells cannot be selected.
Cheers,
Lawrence
Would this link help?
Here's a synopsis:
Over the application, you have four choices:
xlDefault
xlWait
xlBeam
xlNorthwestArrow
You call it like:
Application.Cursor = xlDefault
Over forms, you have more choices. See the article for more.
I don't know what you mean with 'drawing mode'. However, if you want to change the appearance of your mouse cursor, the property you are looking for is Application.Cursor
You can set it to one of four predefined values: xlWait, xlNorthwestArrow, xlIBeam and xlDefault.
If you want to display other cursors, have a look this article on how to display a custom cursor in Access. Since it uses the WinAPI, the solution should work equally in Excel.
Edit:
In response to your edit: I don't think that it is possible to do what you want. The macro recorder doesn't pick it up because there is no VBA command that can do it.
Depending and what you are trying to achieve by switching to design mode, there may be other ways though.
If you want to keep the user from changing the data in your workbook, you can hide the complete Excel window using the Application.Visible property.
If you want to keep the user from selecting or changinganything, but still display the data, have a look at ActiveSheet.Protect or ActiveWorkbook.Protect, available under Tools - Protection.
If you want to move or resize some controls in your workbook, you can do that programmatically by changing the Left, Top, Height and Width property of the control, you don't need to switch to design mode in order to do this from your macro.

VBA Status Bar

I am working on a Word VBA macro app for 80 or so users. The office has high staff turnover, so training suffers, and so one of the self imposed requirements for this project is comprehensive, friendly documentation. However, to supplement this, and to save newbies having to open up a 100 page document when they want to try something new, I want a status bar on every userform (there are five) that provides contextual help. I find tooltips annoying.
I don't have a lot of experience, so I was wanting to
Essentially, I have a file containing every status string. (This is currently a text file, but I was wondering if I should use a spreadsheet or csv for ease of editing by other staff in future.) Every control has a MouseMove event which refers to a function: getStatus(cID) that opens the file, grabs the line and displays it in the status label. It also grabs a few parameters from the same line in the file, such as whether the label is clickable (to link to a page in the help file), and what colour the label should be.
So a few questions really:
Will the application be slow if a userform is constantly referring to a file? It feels fine to me, but I've been in it far too long, and I'm the only user accessing that file. There will be 80 constantly accessing it.
Is MouseMove over a control the best way? Should I instead use co-ordinates?
Most importantly (in terms of me having to do as little work as possible) is there some way to do this so that I do not have to have a MouseMove event on every single control? I have a good few hundred or so controls, each with their own identifier (well, not yet, but they will if this is the only way to do it). Maybe when the form loads I could load ALL the possible status lines so they're ready for whenever the control is moused over. But then, maybe the loading time is negligible?
Appreciate any ideas or thoughts - especially if VBA already has a whole range of functions to do this already and I'm just trying to reinvent the wheel. I can't use the application status bar, because the user rarely sees the application itself.
Thanks!
EDIT:
It is for both data entry, clicking around and a bit of document generation.
It is a controlled environment so macro security issues aren't a big concern for me - and if something goes wrong it's someone else's fault or problem :)
Is this data entry app or do they just click stuff? Because often the field with focus is different to the item the mouse is hovering over, this can cause a lot of confusion.
Constantly reading from a file is a huge waste of time and resources - it is much better to load them only once into an array or collection when the form is loaded.
On MouseMouse event is better than coordinates because you can move things around without worrying. It's a lot of code but you should be able to generate most of that if you have a list of control names because the code should be identical.
ie
Sub Control_MouseMove()
DisplayStatus(Control)
End sub
I would consider the StatusText property and ControlTipText property of controls for this kind of help.
StatusText
This example sets the status bar help text for the form field named "Age."
With ActiveDocument.FormFields("Age")
.OwnStatus = True
.StatusText = "Type your current age."
End With
ControlTipText
This can be assigned from the property sheet for the control.
Private Sub UserForm_Initialize()
MultiPage1.Page1.ControlTipText = "Here in page 1"
MultiPage1.Page2.ControlTipText = "Now in page 2"
CommandButton1.ControlTipText = "And now here's"
CommandButton2.ControlTipText = "a tip from"
CommandButton3.ControlTipText = "your controls!"
End Sub