I tried to search this problem but found no similar issue.
I am still newbie in VBA and I'm trying to create macro which chooses range of cells depending on the user's input and then creates an outlined grid out of those selected cells.
I have two ActiveX buttons in my Excel workbook which let the user to input how big the grid is they want to use (Width & Height). I am struggling to include the above mentioned width and height to my code. Here is the code for the buttons (nothing unclear about them):
Private Sub Height_Click()
Dim Height As Integer
Height = InputBox("Syötä ruudukon korkeus", "Ruudukon korkeus", "Syötä tähän")
Range("E5") = Height
End Sub
And width button:
Private Sub Width_Click()
Dim Width As Integer
Width = InputBox("Syötä ruudukon leveys", "Ruudukon leveys", "Syötä tähän")
Range("E2") = Width
End Sub
I want my grid to start from cell "G2" and expand right&down from there and change the size of the selected cells. However the code I have written isn't working at all (as I thought). Here is the code:
Private Sub CreateGrid_Click()
Columns("G:G+E2").Select
Selection.ColumnWidth = 1
Rows("2:2+E5").Select
Selection.RowHeight = 1
End Sub
Cells "E2" and "E5" have the values of width and height printed, respectively. Nothing happens when I click the CreateGrid-button. Any ideas how I can make this code work? Thanks a lot for all answers.
-Teemu
The trick is use the record macro button.
This function will record all instruction that you are doing with the excel book while is recording
Example:
1.- Start the record macro and type a name for your macro.
2.- Select any cell and type a value
3.- select a range of cells that you want
4.- Press the stop macro recording.
5.- Press Alt +F11 and you will see that excel generate a code of what you did
in excel while the macro recording was turned on, even you can know how to type a value inside a cell or select a range of it.
EDIT:
Private Sub CreateGrid_Click()
Range("G2:" & Range("G2").Offset(Range("E5").Value,Range("E2").Value).Addresslocal).Select
End Sub
If this doesn't do what you expect, please let me know and I will try to help correct it.
the command you're looking for is Range().Select but you'll need to create the string that goes into the parenthesis. So if I understand correct you have stored in variables the number of rows and number of columns you want to offset from G2 right ?
In order to get the column letter you can use the function supplied by microsoft here
Function ConvertToLetter(iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int(iCol / 27)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
but since you're starting from G you'll have to call the function like this:
ConvertToLetter(7+numerColumns)
your final code will look like
Range("G" & 2 + numberLines & ":" & ConvertToLetter(7+numberCols) & numberLines).Select
where numberLines is the number of lines to offset and numberCols the number of columns.
EDIT:
A shorter way, as pointed out by #Kyle, would be to use:
Range("G2").Offset(numberLines,numberCols).Select
Related
I don't know how to take action with the VBA Userform here.
I have a userform which allows users add more textboxes and type the value to the textboxes. I want to copy those values from each additional textbox to separate cells. This is what I did, but not working.
Label "Add textbox after clicking_THIS ONE IS WORKING"
Private Sub CommandButton2_Click()
x = Me.Controls.count + 1
Set xx = Controls.Add("Forms.TextBox.1", "CtrlName" & x)
xx.Top = x * 20 - 108
xx.Left = 396
xx.Width = 288
End Sub
Label "Get value from textboxes to cell_THIS IS NOT WORKING"
Private Sub CommandButton1_Click()
Dim count as Integer
Dim i as Integer
count = Me.Controls.count - 9 ("I have 9 other controls, so need to - 9 to count the number of textboxes")
For i = 1 To count
Cells(i, 1).Select
ActiveCell.Value = Me.Controls("TextBox" & i).Value
Next i
End Sub
The problem is the Me.Controls ("TextBox" & I).Value. I tried different funtions here, but still couldn't solve that.
You have named your textboxes CtrlName10, CtrlName11, etc. You must use those names, not TextBox1 etc. Which means that the value is Me.Controls("CtrlName" & (i + 9)).Value.
Hint: In error box saying Could not find the specified object press the button Debug. This will return you to the code editor, with the offending statement highlighted, and you can examine the variables in the Locals pane (on the View menu).
Seeking help!
Hi,
I am almost done on a project and there's a part I don't understand
I have a + and a - button to add amounts from it's left cell to a total cell on the right (reads 54 in the example) (shown in the link down below)
Also, the amount of times the + is pressed is also calculated on the far most cell (2 for this example)
From the following code I made:
Range("L8").FormulaLocal = "=" & Replace(Range("L8").FormulaLocal, "=", "") & "+" & Range("G8")
The problem is that with the same code, using subtraction, I don't want to see it in the formula bar as it ends up as:
=29+29+29-29-29+29... (2nd image)
I only want to keep the positives. Is there something in the above mentioned code that I can change that will not show the subtraction though and not erase the whole formula that is there already
Thanks!
Part of my excel sheet for better understanding:
What I don't want to see in my formula bar:
First, shouldn't the value in your screenshot be 58, not 54?
Next, does the cell really need to contain a formula? As #teylyn mentioned, just do the calculation in VBA and set the cell's value. E.g. for the + button:
Range("L8").Value = Range("L8").Value + Range("G8").Value
Finally, if you really need to keep the formula, and you know that the value in cell G8 (the value being added or subtracted) never changes between clicks of the + and - buttons, you could first increment the counter (which I assume is cell M8), and then use its value to build the formula.
That might look something like the following, although you'd want to add some error trapping. Also, if you can ensure the counter will never be negative, you could eliminate the ElseIf portion:
Public Sub MinusButton_Click()
Range("M8").Value = Range("M8").Value - 1
Range("L8").FormulaLocal = GetCellFormula
End Sub
Public Sub PlusButton_Click()
Range("M8").Value = Range("M8").Value + 1
Range("L8").FormulaLocal = GetCellFormula
End Sub
Private Function GetCellFormula()
Dim strFormula As String
Dim intNum As Integer
strFormula = "="
If Range("M8").Value > 0 Then
For intNum = 1 To Range("M8").Value
strFormula = strFormula & Range("G8").Value & "+"
Next intNum
ElseIf Range("M8").Value < 0 Then
For intNum = Range("M8").Value To 1 Step -1
strFormula = strFormula & Range("G8").Value & "-"
Next intNum
End If
strFormula = Left(strFormula, Len(strFormula) - 1) 'strip trailing symbol
GetCellFormula = strFormula
End Function
Otherwise, if the value in cell G8 may change, your only option may be to do some (potentially) complicated parsing of the existing formula. If that's the case, please give it a try first, and post a new SO Question if you have any issues.
I was working in a Function that gives me the Column in wich it finds one value.
I was having trouble getting it done...But I made it work!!
The ERROR, believe it or not, was that the Find method has issues with finding values in cells which width is too small...
Could that be so dumb?
This is the call..
Private Sub CommandButton3_Click()
Direccion = BuscarCol(2)
MsgBox "the cell address is " & Direccion
End Sub
And this is the function...
Function BuscarCol(Fecha As Integer) As String
Dim RangoFech As Range
With Sheets("REGISTRO").Range("A1:IN1")
Set RangoFech = .Find(What:=Fecha, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext, MatchCase:=False)
If Not RangoFech Is Nothing Then
BuscarCol = ConvertToLetter(RangoFech.Column)
End If
End With
End Function
Oh, and I have one more for converting Column numbers to letters, but this never was the problem..
Function ConvertToLetter(iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int(iCol / 27)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
So...can you tell me if that is right? The Find method has that problem?
If you choose Look in: Values in the Find box, it will only find values that are visible. If the column is hidden, it won't find it. If the column is too narrow to display the value and it displays ### instead, it won't find it. Even if you format the cell as ;;; to effectively hide the value, it won't find it.
If you choose Look in: Formulas, it will find it in all those cases.
But if you have a formula that produces a value, and that value doesn't exist in the text of the formula, it won't find it. So =200+22 is in a cell and you search for 222
In Values: Only will find it if it's visible
In Formulas: Will not find it
It seems like an odd design decision. My theory is that the algorithm uses the Range.Text property. That property returns what is visible in the cells, such as ### for narrow columns, rather than .Value or .Value2.
I working on a dashboard project where I will have three values: min value, max value and current value. The min and max values will be the end-points of a bar and I'd like to place a text box containing the current value at the appropriate location along the bar. See below:
Is it possible to do this in Excel and if so, how would I go about achieving this. I have some experience with Visual Basic, but I haven't come across this one before.
Ultimately, I am attempting to do an excel version of the dashboard at the following link:
Link to Dashboard
Turn on the macro recording when the Shape-object is not selected. Now select it and change its position. Stop recording and use the code generated.
It looks useful to me when I tried it. I got some IncrementTop and IncrementLeft code. You can also use the Top and Left property directly.
It might be an idea to change the name of the Shape-object into something meaningful (in the address box left of the formula box) so your code gets more readable.
So for my Shape named PositionIndicator:
ActiveSheet.Shapes("PositionIndicator").Left = 250
Or
ActiveSheet.Shapes("PositionIndicator").Left = _
ActiveSheet.Shapes("PositionIndicator").Left + 5
To link it to a cell value just use Range("CELLADDRESS").Value2
To apply it every time you change the cells values use:
Private Sub Worksheet_Change(ByVal Target As Range)
'Here your script to check if the change concerns one of your input cells and then run the code to change the location of the Shape-object
End Sub
Good luck
I like your idea therefore I checked how could the complete code looks like. Here is the result:
Sub SolutionShape(currentVal)
Dim shpBar As Shape, shpCurrent As Shape
'let's assume we have only two shapes on the Activesheet
Set shpBar = ActiveSheet.Shapes(1)
Set shpCurrent = ActiveSheet.Shapes(2)
Dim barMin As Double, barMax As Double
barMin = 0.51 'both values could be taken from sheet
barMax = 6.75
'let's do it visualy complicated this time :)
With shpCurrent
.Left = (-.Width / 2 + shpBar.Left) + _
(((currentVal - barMin) / (barMax - barMin)) * shpBar.Width)
**'EDITED- adding information about current value:**
.TextFrame.Characters.Text = currentVal
End With
End Sub
Call the procedure from event of from immediate window for test, eg.:
SolutionShape 0.51 'go to beginning
SolutionShape 6.75 'go to end
This solution will work wherever you place shapes and whatever new dimensions of them you set.
Assuming the progress bar is a shape on your worksheet (index 1) and textbox is shape index 2; the following moves the textbox along the progress bar based on the % complete.
Note: It will have to be adjusted to offset the portion of the textbox shape that is to the left of the arrow head.
Option Explicit
Public Sub movebox()
Dim textbox As Shape, progbar As Shape
Dim ws As Worksheet
Dim stp As Integer, endp As Integer
Dim tbdyn As Integer
Dim mn As Double, mx As Double, actper As Double, cur As Double
Dim admn As Double, admx As Double
Set ws = Sheets("sheet1")
Set progbar = ws.Shapes(1)
Set textbox = ws.Shapes(2)
'// Far left of progress bar position
stp = progbar.Left
'// Far right of progress bar position
endp = (progbar.Width + stp)
'// Adjust for starting at 0.51
'// You could adjust mn,mx and cur to take the values
'// from the appropriate cells on the spreadsheet
mn = 0.51
mx = 6.07
admn = 0
admx = 6.07 - mn
cur = 4
'// Calculate percentage complete
actper = cur / admx
'// Apply percentage to progress bar
tbdyn = actper * endp
'// Move the textox appropriately
textbox.Left = tbdyn
End Sub
Is there any way of finding the height of the ROWS from 1 to 50, and the width of the COLUMNS from A to Z in an Excel sheet without manually clicking and writing down the answer?
Thanks
Michael.
To add on top of #Parkyprg
Range("A1:A50").Height ' height of range
Range("A:Z").Width ' width of range
Range("A1:A50").Rows.Count ' number or rows in range
Range("A3").Height ' height of A3 cell
Range("A3").Width ' width of A3 cell
In Excel VBA you can use something like this:
Range("A1:A50").Height
and
Range("A:Z").Width
In Excel vba, getting an output of the row heights is easy to iterate through using the rows.height property:
Sub outputRowHeight()
Dim i As Integer
For i = 1 To 50
Debug.Print Rows(i).Address & " is : " & Rows(i).Height
Next i
End Sub
For the column width, we use columns.width property. It is a little trickier because you can't directly iterate through letters of the alphabet, so we need to use the index instead:
Sub outputColumnWidths1()
Dim i As Integer
For i = 1 To 26 '26th letter is Z
Debug.Print Columns(i).Address & " is : " & Columns(i).Width
Next i
End Sub
If you want to avoid having to know the index of a letter, you can use an if statement to exit once you're out of range:
Sub outputColumnWidths2()
Dim i As Integer
For i = 1 To 99 'using 99 as arbitrary high end number
If Columns(i).Address <> "$AA:$AA" Then
Debug.Print Columns(i).Address & " is : " & Columns(i).Width
Else 'once we get outside of A-Z, we want to end.
Exit For
End If
Next i
End Sub
This will produce the same results as the first example, but you can extend it to as many columns you want to by bumping up the iteration number and the first column name of the first one you don't want to evaluate.
Hope this helps!