Strange error with Selection object and Userform - vba

Getting a strange error with this code. This excerpt is the beginning of the main code. First it opens a form that takes 3 inputs. The inputs aren't being used right now so it's not the issue.
Public triangle As Range
Public Height, Width, i As Integer
Sub asdf()
Set triangle = Selection
WeightsUserForm.Show
Height = triangle.Rows.Count
Width = triangle.Columns.Count
Debug.Print Height
Debug.Print Width
This gives me 12 as Height and 12 as Width, which is correct based on what I've selected.
Now here is the sub that runs when you press OK on the user form:
Private Sub OKButton_Click()
Set triangle = Selection
Height = triangle.Rows.Count
Width = triangle.Columns.Count
Debug.Print Height
Debug.Print Width
This gives me Height as 28.5 and Width as 99. I have no clue where this comes from. I even checked all the objects on my userform as if maybe it was interpreting that as my selection (which is clearly wrong since those objects wouldn't have a rows property).
Ideally I would like to save my initial selection as a "public variable" if that is a real thing.
Any help is appreciated.
EDIT: Further update. I have set the variable triangle manually now ie
triangle = Range("B3","M14")
This STILL gives me the same strange dimensions. Now I'm really stumped.
2xEDIT: When I don't use the variables Height and Width and just refer directly to triangle.Rows.Count and triangle.Columns.Count it gives me correct answers. So I can run my program properly now. I would still love to know why using a variable was wrong though.
So you're saying that the line
Public Height,Width,i As Integer
is only declaring i as an integer and not specifying a type for height and width? If so that would be my problem.
I redid it declaring both Height and Width properly as integers but it still bugged out the same way. However using private variables W and H defined the same way it works. shrug

Reading between the lines, I think your issue is that Debug.Print Height and Debug.Print Width is printing the size of your form.
This will happen if your declarations are in a Module rather than the Form class, because Height and Width are keywords applicable to the form, so the local versions are used in preference.
To solve, you should do all of these things (not all of this is absolutely necassary, but is all good practice):
Use Option Explicit in all your modules
Don't use Keywords for variable names
Scope your variables, in order of preference, to Procedure, then local Module, then public Module, and only when there is good reason
Prefix your remote module calls with the module name, eg Module1.Height
BTW, using Dim Height, Width, i as integer declares declares Height and Width as the default type which is Variant.

Related

PowerPoint VBA pass BUILT IN enumeration value to function

I'm building a ribbon tab and several of the buttons insert textboxes (each with differing formats).
I have built a 'CreateTextBox' function that takes as input parameters (i) the active slide, (ii) box width, (iii) box height this works fine
I want to add a fourth parameter which is whether or not it should auto-size (so a PpAutoSize constant):
https://learn.microsoft.com/en-us/office/vba/api/powerpoint.textframe.autosize
Example of how this would play out is a line in the sub that links to the button being:
Set NewTextBox = CreateTextBox(CurrentSlide, 200, 100, ppAutoSizeNone)
But, nothing I've tried allows me to pass that constant in a way that it could be picked up like this in the function CreateTextBox:
Function CreateTextBox(sld As Slide, tbWidth As Double, tbHeight As Double, AutoSizeConstant as ???????) as Shape
Set CreateTextBox = sld.Shapes.AddTextbox(.........)
With CreateTextBox
...
...
.TextFrame.AutoSize = AutoSizeConstant
End With
End Function
Everything I can find talks about creating a custom enumeration and passing the index of the item you want. I don't want to duplicate anything or have to use class modules, just want to pass the constant per the above.
Any ideas?
Per comment from freeflow, you can specify the enumeration as the type so 'ByVal AutosizeConstant as PpAutoSize' works. Thank you!

Change Excel forms Label Length to match the length of it's text using VBA

How can I get an Excel Form Control Label which is on a worksheet to change it's length to match the length of the sting of characters in it's caption. Importantly it must work irrispective of what screen the file is viewed on or what the zoom setting is on the sheet.
So far I've got:
Sub LabelLength()
Dim XYLabel As Shape
Dim XYDataSheet As Worksheet
Set XYDataSheet = ThisWorkbook.Sheets(1)
Set XYLabel = XYDataSheet.Shapes(1) 'This is the Forms Label
XYLabel.OLEFormat.Object.Caption = Trim(XYDataSheet.Cells(1, 1).Value)
XYLabel.Width = Len(Trim(XYDataSheet.Cells(1, 1).Value)) * 7.5
End Sub
Which works, but does leave quite a lot of space after some captions.
I don't think this can be done with a Form control, at least not directly. If you want to stick with a Form control, I think you're on the right track with scaling its .width property based on the text size. To do it better than that, you'd probably have to build a dictionary object or something and sum the width of all characters in the string based on the width you had listed in the dictionary object.
However, if you can switch your label to an ActiveX control, then you can solve this by using:
.WordWrap = False
.AutoSize = True
I think people in general prefer to use Form controls because they're a bit more simple. But I also think, in general, ActiveX controls have more flexibility and you can customize them to your needs more. You can read a bit more on Form controls vs. ActiveX controls here.

Visual Basic 2010 using .left

i want to know if what is the thing that calculate when i call "object.LEFT" in visual basic express 2010, same thing as right bottom and .top..
thankz in advance! ^^
object.left is a property of a control that specifies its relative distance (in pixels) from the control's parent container.
For example: if you have object.left set to 50, then it will push the control in 50 pixels from the left side of the container (i.e. a Form in WinForms development or Page in ASP.NET development).
Yes, I could be more specific if you provided more specific detail about the specific object, and what your purpose was.
In VB there are .Left, .Top, .Width and .Height properties that are usually measured in screen pixels to define the position and size of a Control (ListBox, CheckBox, TextBox, etc) on a Form. Footnote: VBForms can be set to use twips, points, centimeters and inches as their basic measurement.
In Office (Word, PowerPoint, Excel) there are controls that are similar but NOT the same exactly as those in VB UI. They can be placed on a UserForm using these same properties. To place them on a Word document however, you need the .GetPoint method that allows you to specify a .Range object on your document and this function will fill-in the placement information
myWorkingDoc.Windows.Item(1).GetPoint ScPixLeft, ScPixTop, ScPixWidth, ScPixHeight, _
TblControl.Rows.Item(4).Cells.Item(1).Range.OMaths.Item(1).Range
The above line defines 4 Long integers: ScPixLeft, ScPixTop, ScPixWidth, ScPixHeight and a Range object in a word document, in the above case a Word Table named TblControl, the 4th row, 2nd (cell) column. WIthin a Word document window object the .GetPoint method gives one the relative placement, in pixels, within the document window. I use ScPixWidth and ScPixHeight to give me the size of the math equation (OMath object) so I can size an InlineShape to contain it.

Vb.net - Setting a controls margin value

So, I'm adding a label programatically and I'm in need of altering the top margin a little bit to the value 8. I can't do that the obvious way, so what's wrong with my thinking?
Dim LabelAdapter As New Label
LabelAdapter.text = "Adapter"
LabelAdapter.Margin.Top = 8
This gives me the error "Expression is a value and therefore cannot be the target of an assignment".
Label.Margin returns a Padding object.
Since Padding is a structure, it will actually return a copy. You are changing the Top value of that copy, not of the actual control’s margin. Since that would have no noticeable effect, VB correctly prevents it.
You need to assign a whole new margin. In fact, the Margin property (or rather, the Padding class) is arguably broken since it doesn’t allow an easy way to change the individual values.
Unfortunately, we just have to live with it. So to change just the Top value, we need to write:
Dim old As Padding = LabelAdapter.Margin
LabelAdapter.Margin = New Padding(old.Left, 8, old.Right, old.Bottom)
Weird, huh?

The control or subform control is too large for this location on resize

I have a simple form in Access 2003. The form has a List control and a button. I wanted to make the list to resize with the form (only vertically) while the button remains at the bottom right of the List. I'm using the following code on the form's resize event.
list.Height = Me.InsideHeight - list.Top - 200
commandButton.Top = list.Height + list.Top + 50
This works fine as I resize the form, until the form height gets to a certain height. Then I get this error;
Run-time error '2100':
The control or subform control is too large for this location
This error is occurring at the line where I'm assigning the commandButton.Top. If I remove this line then the list height changes fine. I don't have any subforms in the form.
Does anyone know why this is happening?
Thanks
I think it is because you need to resize the detail section of the form first.
Try changing the code to
Me.Section(0).Height = Me.InsideHeight
list.Height = Me.InsideHeight - list.Top - 200
commandButton.Top = list.Height + list.Top + 50
Came by here (as many have) with the same problem and then realised my issue. Be mindful when resizing a control to a larger size with regard to the order of setting properties.
I would recommend setting the TOP and LEFT positions before HEIGHT and WIDTH.
Although my final sized control should have fitted OK once resized, I had originally tried setting the WIDTH first which attempted to enlarge the control exceeding the width of the form. My application threw the 2100 error at that point. I really hope this helps someone! Also, don't forget to set dimensions in TWIPS which is set as INCHESS x 1440 (or CM x 566.9291), ie: .Width = 10 * 566.9291 to set a control width to 10cm.
I get this same error if I set the width to greater the 31680.
With a little more research, I notice MS Access only allows a form width to be 22" wide. 22" = 31680 TWIPS.
So my workaround solutions it to add a check:
If newWidth > 31680 Then newWidth = 31680