Using this to create a button:-
Sub CreateButton4()
Dim i&
With ActiveSheet
i = .Shapes.Count
With .Buttons.Add(199.5, 20 + 46 * i, 81, 36)
.Name = "New Button" & Format(i, "00")
.OnAction = "MoveValue"
.Characters.Text = "Submit " & Format(i, "00")
End With
End With
That runs the MoveValue() sub:-
Sub MoveValue()
With Sheets("Sheet1").Columns(8).Find(Range("C3").Value, , , 1).Offset(0, 1)
.Value = .Value + Sheets("Sheet1").Range("D3").Value
End With
The problem is I want MoveValue() to relate to the cells adjacent to it as I have another sub which submits data to the adjacent cells when the button is created (at the moment I've only written it to work for the first button). Not sure if I'm going about this completely the wrong way. Any help would be appreciated.
Image Spreadsheet1
You can use the property TopLeftCell as shown here. But you have to change your layout like this, so the top left cell of your button is in the same row as the information you want.
Sub CreateButton4()
Dim i&
With ActiveSheet
i = .Shapes.Count
With .Buttons.Add(199.5, 35 + 46 * i, 81, 36)
.Name = "New Button" & Format(i, "00")
.OnAction = "MoveValue"
.Characters.Text = "Submit " & Format(i, "00")
End With
End With
End Sub
Sub MoveValue()
Dim tlcRow As Integer
tlcRow = ActiveSheet.Shapes(Application.Caller).TopLeftCell.row
With Plan1
.Range("H3:H8").Find(.Range("C" & tlcRow).Value).Offset(0, 1).Value = .Range("D" & tlcRow).Value
End With
End Sub
Related
How do I get this to work?
I have this code written so far:
Sub RemoveLoop()
Dim i As Long
For i = 6 To 15
If Range("B" + i) = "YES" Then
Range("C" + i + ":" + "P" + i).ClearContents
End If
Next i
End Sub
Instead of doing each individually like this:
This is what I'm trying to shorten/accomplish, below:
Sub Remove()
If Range("B6") = "YES" Then
Range("C6:P6").ClearContents
End If
If Range("B7") = "YES" Then
Range("C7:P7").ClearContents
End If
If Range("B8") = "YES" Then
Range("C8:P8").ClearContents
End If
If Range("B9") = "YES" Then
Range("C9:P9").ClearContents
End If
If Range("B10") = "YES" Then
Range("C10:P10").ClearContents
End If
If Range("B11") = "YES" Then
Range("C11:P11").ClearContents
End If
If Range("B12") = "YES" Then
Range("C12:P12").ClearContents
End If
If Range("B13") = "YES" Then
Range("C13:P13").ClearContents
End If
If Range("B14") = "YES" Then
Range("C14:P14").ClearContents
End If
If Range("B15") = "YES" Then
Range("C15:P15").ClearContents
End If
End Sub
Simple question for you guys, thank you for your help.
I don't know what else to say, it's pretty straight forwards I believe. But I'm still getting the, "Looks like your most is mostly code error."
This should be an easy one for you VBA experts to solve.
Thanks again.
Try this:
Sub RemoveLoop()
Dim i As Long
Set WSheet = Worksheets("Sheet1") ' This enables the change in the mentioned sheet and not the Active sheet.
For i = 6 To 15
If WSheet.Range("B" & i) = "YES" Then
WSheet.Range("C" & i & ":P" & i).ClearContents
End If
Next i
End Sub
This is what you can do, passing the cells and the ranges as variables:
Option Explicit
Sub RemoveLoop()
Dim i As Long
For i = 6 To 15
With Worksheets(1)
If UCase(.Range("B" & i)) = "YES" Then
.Range(.Cells(i, "C"), .Cells(i, "P")).ClearContents
End If
End With
Next i
End Sub
Except for using Range(Cells,Cells), the code is refering to UCase, which makes sure that "yes" and "YES" in column "B" are treaten equally.
First off, ill give credit where credit is due. This is put together using code from u/Joe Was from Mr.Excel.com and exceltip.com.
Now that I have gotten that out of the way I am trying to create a search function that will search through my 9 sheet document in excel, to find a value that was typed into a search box. Then paste those values onto the first page of the workbook.
What do I need to change in my code to make it paste to the right place on the search page? I have tried changing things in the last loop because that is where I get the "Run-Time error 91. Object variable or with block variable not set".
I've googled that error, but variables always screw me up so that may be the problem.
The search page.
This is where the Debugger stops.
This is my code so far.
Sub Find_one()
'Find Function For ERF Spreadsheet'
'Type in Box, Press Button, Display the Results'
Dim ws As Worksheet, Found As Range
Dim myText As String, FirstAddress As String
Dim AddressStr As String, foundNum As Integer
myText = Range("D5")
If myText = "" Then Exit Sub
For Each ws In ThisWorkbook.Worksheets
With ws
'Do not search sheet1'
If ws.Name = "Sheet1" Then GoTo myNext
Set Found = .UsedRange.Find(What:=myText, LookIn:=xlValues, LookAt:=xlPart, MatchCase:=False)
If Not Found Is Nothing Then
FirstAddress = Found.Address
Do
foundNum = foundNum + 1
AddressStr = AddressStr & .Name & " " & Found.Address & vbCrLf
Set Found = .UsedRange.FindNext(Found)
'Found.EntireRow.Copy _
'Destination:=Worksheets("Sheet4").Range("A65536").End(xlUp).Offset(1, 0)
Loop While Not Found Is Nothing And Found.Address <> FirstAddress
End If
myNext:
End With
Next ws
If Len(AddressStr) Then
Sheet8.Range("B18") = ws.Cells(x, 1)
Sheet8.Range("C18") = ws.Cells(x, 2)
Sheet8.Range("D18") = ws.Cells(x, 3)
Sheet8.Range("E18") = ws.Cells(x, 4)
Sheet8.Range("F18") = ws.Cells(x, 5)
Sheet8.Range("G18") = ws.Cells(x, 6)
Sheet8.Range("H18") = ws.Cells(x, 7)
Sheet8.Range("I18") = ws.Cells(x, 8)
Sheet8.Range("J18") = ws.Cells(x, 9)
Else:
MsgBox "Unable to find " & myText & " in this workbook.", vbExclamation
End If
End Sub
This is the original code for the last loop...
If Len(AddressStr) Then
MsgBox "Found: """ & myText & """ " & foundNum & " times." & vbCr & _
AddressStr, vbOKOnly, myText & " found in these cells"
Else:
MsgBox "Unable to find " & myText & " in this workbook.", vbExclamation
End If
Here, try this out. I redid how I interpreted the first section. I'm not entirely sure what you're trying to do with everything so let me know if this works or where it went wrong.
Sub FindOne()
Dim k As Integer
Dim myText As String, searchColumn As String
Dim totalValues As Long
Dim nextCell As Range
k = ThisWorkbook.Worksheets.Count
myText = Sheets(1).Range("D5").Value
If myText = "" Then
MsgBox "No Address Found"
Exit Sub
End If
Select Case ComboBox1.Value
Case "Equipment Number"
searchColumn = "A"
Case "Sequence Number"
searchColumn = "B"
Case "Repair Order Number(s)"
searchColumn = "D"
Else
MsgBox "Please select a value for what you are searching by."
End Sub
End Select
For i = 2 To k
totalValues = Sheets(i).Range("A65536").End(xlUp).Row
ReDim AddressArray(totalValues) As String
For j = 0 To totalValues
AddressArray(j) = Sheets(i).Range(searchColumn & j + 1).Value
Next j
For j = 0 To totalValues
If (InStr(1, AddressArray(j), myText) > 0) Then
Set nextCell = Sheets(1).Range("A65536").End(xlUp).Offset(1, 0)
Range(nextCell, nextCell.Offset(0, 8)).Value = Sheets(i).Range("A" & j, "I" & j).Value
End If
Next j
Next i
End Sub
Also I have no clue what that second part of the code is supposed to be, so if you want to elaborate on the section with If Len(AddressStr) Then, I'd appreciate it because that really doesn't even work as an If...Then statement lol :)
I am currently working on the following code which is searching through all tabs in an excel workbook, selects all currencies greater a certain threshold in a defined column "J" and if criteria is met the line containing the currency that is greater threshold is pasted in a new created tab called "summary".
Now my question is:
1. Is there any chance to make this code more interactive? What I would like to do, is to add an inputbox in which the user is typing his threshold (in my example 1000000) and this threshold is used for looping through all tabs.
2. It would be great to get an input box like "select column containing currency", as column "J" won't be set all time, it could also be another column ("I", "M" etc) however this will be the same for all sheets then.
3. Any chance to select certain sheets within workbook (STRG + "sheetx" "sheety" etc....) which are then pasted into my loop and all others are neglected?
Any help, especially for my issues within question 1 and 2 is appreciated. Question 3 would only be a "nice-to-have" thing
Option Explicit
Sub Test()
Dim WS As Worksheet
Set WS = Sheets.Add
WS.Name = "Summary"
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
With Sheets("Summary")
.Cells.Clear
End With
j = 2
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Summary" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastRow
If sh.Range("J" & i) > 1000000 Or sh.Range("J" & i) < -1000000 Then
sh.Range("a" & i & ":n" & i).Copy Destination:=Worksheets("Summary").Range("A" & j)
Sheets("Summary").Range("N" & j) = sh.Name
j = j + 1
End If
Next i
End If
Next sh
Sheets("Summary").Columns("A:N").AutoFit
End Sub
You may want to try this
Option Explicit
Sub Test()
Dim WS As Worksheet
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
Dim sheetsList As Variant
Dim threshold As Long
Set WS = GetSheet("Summary", True)
sheetsList = Array("STRG","sheetx","sheety") '<--| fill this array with the sheets names to be looped through
threshold = Application.InputBox("Input threshold", Type:=1)
j = 2
For Each sh In ActiveWorkbook.Sheets(sheetsList)
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastRow
If sh.Range("J" & i) > threshold Or sh.Range("J" & i) < -threshold Then
sh.Range("a" & i & ":n" & i).Copy Destination:=WS.Range("A" & j)
WS.Range("N" & j) = sh.Name
j = j + 1
End If
Next i
Next sh
WS.Columns("A:N").AutoFit
End Sub
Function GetSheet(shtName As String, Optional clearIt As Boolean = False) As Worksheet
On Error Resume Next
Set GetSheet = Worksheets(shtName)
If GetSheet Is Nothing Then
Set GetSheet = Sheets.Add(after:=Worksheets(Worksheets.count))
GetSheet.Name = shtName
End If
If clearIt Then GetSheet.UsedRange.Clear
End Function
You can set a UserForm as input into the program - something like what follows. You only need to run the 'CreateUserForm' sub once to get the UserForm1 event handlers set up in your spreadsheet. Once that's done you can run the 'Test' to see the UserForm1 itself. You can edit the event handlers to check the user input or reject it if need be. Also once the UserForm1 is set up you can move the various labels and listboxes around and, of course, create new ones. It should look like this:
You can select as many sheets as required from the last listbox and the selections will be added to a vba Collection. See the MsgBox at the beginning of your code and play with entering values/selections into the user box to see what it does.
The UserForm handler that's called when you press the okay button will save the selections to global variables so that they can be picked up in the code.
Option Explicit
' Global Variables used by UserForm1
Public lst1BoxData As Variant
Public threshold As Integer
Public currencyCol As String
Public selectedSheets As Collection
' Only need to run this once. It will create UserForm1.
' If run again it will needlessly create another user form that you don't need.
' Once it's run you can modify the event handlers by selecting the UserForm1
' object in the VBAProject Menu by right clicking on it and selecting 'View Code'
' Note that you can select multiple Sheets on the last listbox of the UserForm
' simply by holding down the shift key.
Sub CreateUserForm()
Dim myForm As Object
Dim X As Integer
Dim Line As Integer
'This is to stop screen flashing while creating form
Application.VBE.MainWindow.Visible = False
Set myForm = ThisWorkbook.VBProject.VBComponents.Add(3)
'Create the User Form
With myForm
.Properties("Caption") = "Currency Settings"
.Properties("Width") = 322
.Properties("Height") = 110
End With
' Create Label for threshold text box
Dim thresholdLabel As Object
Set thresholdLabel = myForm.Designer.Controls.Add("Forms.Label.1")
With thresholdLabel
.Name = "lbl1"
.Caption = "Input Threshold:"
.Top = 6
.Left = 6
.Width = 72
End With
'Create TextBox for the threshold value
Dim thresholdTextBox As Object
Set thresholdTextBox = myForm.Designer.Controls.Add("Forms.textbox.1")
With thresholdTextBox
.Name = "txt1"
.Top = 18
.Left = 6
.Width = 75
.Height = 16
.Font.Size = 8
.Font.Name = "Tahoma"
.borderStyle = fmBorderStyleSingle
.SpecialEffect = fmSpecialEffectSunken
End With
' Create Label for threshold text box
Dim currencyLabel As Object
Set currencyLabel = myForm.Designer.Controls.Add("Forms.Label.1")
With currencyLabel
.Name = "lbl2"
.Caption = "Currency Column:"
.Top = 6
.Left = 100
.Width = 72
End With
'Create currency column ListBox
Dim currencyListBox As Object
Set currencyListBox = myForm.Designer.Controls.Add("Forms.listbox.1")
With currencyListBox
.Name = "lst1"
.Top = 18
.Left = 102
.Width = 52
.Height = 55
.Font.Size = 8
.Font.Name = "Tahoma"
.borderStyle = fmBorderStyleSingle
.SpecialEffect = fmSpecialEffectSunken
End With
' Create Label for sheet text box
Dim sheetLabel As Object
Set sheetLabel = myForm.Designer.Controls.Add("Forms.Label.1")
With sheetLabel
.Name = "lbl3"
.Caption = "Select Sheets:"
.Top = 6
.Left = 175
.Width = 72
End With
'Create currency column ListBox
Dim sheetListBox As Object
Set sheetListBox = myForm.Designer.Controls.Add("Forms.listbox.1")
With sheetListBox
.Name = "lst3"
.Top = 18
.Left = 175
.Width = 52
.Height = 55
.Font.Size = 8
.MultiSelect = 1
.Font.Name = "Tahoma"
.borderStyle = fmBorderStyleSingle
.SpecialEffect = fmSpecialEffectSunken
End With
'Create Select Button
Dim selectButton As Object
Set selectButton = myForm.Designer.Controls.Add("Forms.commandbutton.1")
With selectButton
.Name = "cmd1"
.Caption = "Okay"
.Accelerator = "M"
.Top = 30
.Left = 252
.Width = 53
.Height = 20
.Font.Size = 8
.Font.Name = "Tahoma"
.BackStyle = fmBackStyleOpaque
End With
' This will create the initialization sub and the click event
' handler to write the UserForm selections into the global
' variables so they can be used by the code.
myForm.CodeModule.InsertLines 1, "Private Sub UserForm_Initialize()"
myForm.CodeModule.InsertLines 2, " me.lst1.addItem ""Column I"" "
myForm.CodeModule.InsertLines 3, " me.lst1.addItem ""Column J"" "
myForm.CodeModule.InsertLines 4, " me.lst1.addItem ""Column M"" "
myForm.CodeModule.InsertLines 5, " me.lst3.addItem ""Sheet X"" "
myForm.CodeModule.InsertLines 6, " me.lst3.addItem ""Sheet Y"" "
myForm.CodeModule.InsertLines 7, " lst1BoxData = Array(""I"", ""J"", ""M"")"
myForm.CodeModule.InsertLines 8, "End Sub"
'add code for Command Button
myForm.CodeModule.InsertLines 9, "Private Sub cmd1_Click()"
myForm.CodeModule.InsertLines 10, " threshold = CInt(Me.txt1.Value)"
myForm.CodeModule.InsertLines 11, " currencyCol = lst1BoxData(Me.lst1.ListIndex)"
myForm.CodeModule.InsertLines 12, " Set selectedSheets = New Collection"
myForm.CodeModule.InsertLines 13, " For i = 0 To Me.lst3.ListCount - 1"
myForm.CodeModule.InsertLines 14, " If Me.lst3.Selected(i) = True Then"
myForm.CodeModule.InsertLines 15, " selectedSheets.Add Me.lst3.List(i)"
myForm.CodeModule.InsertLines 16, " End If"
myForm.CodeModule.InsertLines 17, " Next"
myForm.CodeModule.InsertLines 18, " Unload Me"
myForm.CodeModule.InsertLines 19, "End Sub"
'Add form to make it available
VBA.UserForms.Add (myForm.Name)
End Sub
' This is your code verbatim except for now
' the UserForm is shown for selecting the
' 1) currency threshold, 2) the column letter
' and 3) the sheets you want to process.
' The MsgBox just shows you what you've
' selected just to demonstrate that it works.
Sub Test()
Dim WS As Worksheet
Set WS = Sheets.Add
WS.Name = "Summary"
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
With Sheets("Summary")
.Cells.Clear
End With
'**** Start: Running & Checking UserForm Output ****
UserForm1.Show
Dim colItem As Variant
Dim colItems As String
For Each colItem In selectedSheets:
colItems = colItems & " " & colItem
Next
MsgBox ("threshold=" & threshold & vbCrLf & _
"currencyCol=" & currencyCol & vbCrLf & _
"selectedSheets=" & colItems)
'**** End: Running & Checking UserForm Output ****
j = 2
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Summary" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).row
For i = 4 To lastRow
If sh.Range("J" & i) > 1000000 Or sh.Range("J" & i) < -1000000 Then
sh.Range("a" & i & ":n" & i).Copy Destination:=Worksheets("Summary").Range("A" & j)
Sheets("Summary").Range("N" & j) = sh.Name
j = j + 1
End If
Next i
End If
Next sh
Sheets("Summary").Columns("A:N").AutoFit
End Sub
The following code works for my purposes except the selection of single tabs to loop through:
Option Explicit
Sub Test()
Dim column As String
Dim WS As Worksheet
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
Dim sheetsList As Variant
Dim threshold As Long
Set WS = GetSheet("Summary", True)
threshold = Application.InputBox("Input threshold", Type:=1)
column = Application.InputBox("Currency Column", Type:=2)
j = 2
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Summary" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastRow
If sh.Range(column & i) > threshold Or sh.Range(column & i) < -threshold Then
sh.Range("a" & i & ":n" & i).Copy Destination:=WS.Range("A" & j)
WS.Range("N" & j) = sh.Name
j = j + 1
End If
Next i
End If
Next sh
WS.Columns("A:N").AutoFit
End Sub
Function GetSheet(shtName As String, Optional clearIt As Boolean = False) As Worksheet
On Error Resume Next
Set GetSheet = Worksheets(shtName)
If GetSheet Is Nothing Then
Set GetSheet = Sheets.Add(after:=Worksheets(Worksheets.Count))
GetSheet.Name = shtName
End If
If clearIt Then GetSheet.UsedRange.Clear
End Function
Apologies, the Title is slightly misleading. Rather than switch the row/column (select a graph, then on the design tab, click "Switch Row/Column") in excel, I would like to force it initially, mitigating the need to change.
My code is as below, adding another column the rows/columns have switched automatically:
Sub InsertBar(rngToPrint As Range, lngTopleft As String, BottomLeft As String)
Dim strRange As String
Dim rngChart As Range
Dim myChart As Chart
lngStartRow = Sheets(rngToPrint.Worksheet.Name).Range(lngTopleft).Row
lngEndRow = Sheets(rngToPrint.Worksheet.Name).Range(BottomLeft).Row
Sheets(rngToPrint.Worksheet.Name).Activate
'Correct
'Sheets(rngToPrint.Worksheet.Name).Range("$A$" & CStr(lngStartRow) & ":$D$" & CStr(lngEndRow)).Select
'Shows Flipped Axis
Sheets(rngToPrint.Worksheet.Name).Range("$A$" & CStr(lngStartRow) & ":$E$" & CStr(lngEndRow)).Select
Set myChart = ActiveSheet.Shapes.AddChart(xlColumnClustered, 500, 10, , 175).Chart
With myChart
.ChartArea.Format.TextFrame2.TextRange.Font.Size = 8
.HasTitle = True
.ChartTitle.Text = rngToPrint.Worksheet.Name & " Receiving Sim Stats - (Today Only)"
.SeriesCollection(1).Name = Range("B" & lngStartRow - 1).Value
.SeriesCollection(2).Name = Range("C" & lngStartRow - 1).Value
.SeriesCollection(3).Name = Range("D" & lngStartRow - 1).Value
'Dataseries which has just been added
.SeriesCollection(4).Name = Range("E" & lngStartRow - 1).Value
End With
End Sub
For anyone else interested, the answer I found in the end was this:
With myChart
.PlotBy = xlColumns
Or if you would like to switch this the other way:
myChart.PlotBy = xlRows
I hope I make this clear:
I have a loop that copies some hyperlinks in specific cells (they come from a document list with the file path, document name, etc stored in another sheet).
I would like to have an icon next to the hyperlink that indicates if it will open a word document, a folder, etc. In the document list, I can put an indicator in the column next to the hyperlink (1 for word doc, 2 for folder, etc) so that depending on the case, the right icon gets sent next to the right type of document hyperlink.
I have managed to do it by simply inserting shapes (blue rectangle for word doc, green for folder) but I'd like to have a more descriptive symbol (like a specific FaceID maybe?). Here is my code (dumbed down for simplicity):
Sub Icons()
Dim i As Integer
Dim sh As Object
'Only loops through A1:A5 for simplicity
'Looks at the associated indicator located in the previous sheet
'Assigns a shape depending if it is 1 or 2
For i = 1 To 5
If Feuil1.Range("A" & i) = "1" Then
Set sh = Feuil2.Shapes.AddShape(msoShapeRectangle, Range("A"& i).Left, Range("A" & i).Top, 15, 15)
sh.Name = "WordDocIcon" & i
sh.Fill.ForeColor.RGB = RGB(0, 220, 220)
End If
If Feuil1Range("A" & i) = "2" Then
'It is easy to do when inserting a given msoShape, but I want something else!
Set sh = Feuil2.Shapes.AddShape(msoShapeRectangle, Range("A" & i).Left, Range("A" & i).Top, 15, 15)
sh.Name = "FolderIcon" & i
sh.Fill.ForeColor.RGB = RGB(100, 100, 0)
End If
Next
End Sub
Further to my comments, Here is how you can insert pictures and position them in say Column B. I would still say that typing "Word" or "Folder" in Column B and then coloring the cell would be much simpler :)
Sub Sample()
Dim ws As Worksheet
Dim picWord As String
Dim picFolder As String
Dim Shp As Shape
Dim i As Long
picWord = "C:\Users\Siddharth\Desktop\Word.Jpg"
picFolder = "C:\Users\Siddharth\Desktop\folder.Jpg"
Set ws = ThisWorkbook.Sheets("Feuil1")
With ws
For i = 1 To 5
If .Range("A" & i) = "1" Then
With .Pictures.Insert(picWord)
With .ShapeRange
.LockAspectRatio = msoTrue
.Width = ws.Range("B" & i).Width
.Height = ws.Range("B" & i).Height
End With
.Left = ws.Range("B" & i).Left
.Top = ws.Range("B" & i).Top
.Placement = 1
.PrintObject = True
End With
ElseIf .Range("A" & i) = "2" Then
With .Pictures.Insert(picFolder)
With .ShapeRange
.LockAspectRatio = msoTrue
.Width = ws.Range("B" & i).Width
.Height = ws.Range("B" & i).Height
End With
.Left = ws.Range("B" & i).Left
.Top = ws.Range("B" & i).Top
.Placement = 1
.PrintObject = True
End With
End If
Next i
End With
End Sub
I used the following pictures. You can download these or use whatever you like.
When you run the above code, you will get this kind of output