How to get offset range to work in formula? - excel

I'm having trouble getting an offset range into a formula. The idea is to have a user input the text they want to search for in a string, the value if found, and the value if not found. And then turn all of that into a formula that gets inserted in the selected cell in the active sheet. The problem is that the formula returns the value of SearchCell and not the range.
How can I put the range of SearchCell in the formula and not the value of SearchCell?
Sub SearchString()
Dim SelectedCell As Range
Dim SearchCell As Range
Dim SearchValue As Variant
Dim FoundValue As Variant
Dim NotFoundValue As Variant
Set SelectedCell = Application.Selection
Set SearchCell = SelectedCell.Offset(, -1)
SearchValue = InputBox("What do you want to search for?")
FoundValue = InputBox("If found?")
NotFoundValue = InputBox("If not found?")
SelectedCell.Formula = "=IF(ISNUMBER(SEARCH(""*" & SearchValue & "*""," & SearchCell & ")), _
""" & FoundValue & """, """ & NotFoundValue & """)"
End Sub

SearchCell.Address(RowAbsolute:=False, ColumnAbsolute:=False)

Related

Print multiple copies of the same sheet, but replace one cell with the data from a list (range) from another sheet

I am trying to print a few months worth of time sheets. So print 20 copies of the same sheet, and change the date on one cell (cell "C1" on "Timesheets" sheet) using a list of fortnightly dates on the "Pay Periods" sheet.
Have tried multiple methods but can't get close for varying reasons...
Would be interested to learn why am getting errors or stuck on each method I have tried below.
Sub PrintAllDates()
Dim printDate As Date
Dim startDate As Date
Dim endDate As Date
startDate = Worksheets("Pay Periods").Range("A2")
endDate = Worksheets("Pay Periods").Range("A10")
For printDate = startDate To endDate
Sheets("Timesheet").Range("C1") = printDate
Sheets("Timesheet").PrintOut
Next
This works but I can't figure out how to get it to use the list.
It prints out 9 consecutive days instead, whereas my list is 9 consecutive "fortnights".
Sub PrintCopies()
Dim i As Integer
Dim VList As Variant
VList = Sheets("Pay Periods").Range("H2:H3").Value
For i = LBound(VList) To UBound(VList)
Range("C1") = VList(i)
ActiveSheet.PrintOut
Next
With the above, I get runtime error 9 "Subscript out of range" on Range("C1") = VList(i)
Sub PrintCopies()
Dim i As Date
Dim VList As Variant
VList = Array(Worksheets("Pay Periods").Range("A2:A10"))
For i = LBound(VList) To UBound(VList)
Sheets("Timesheet").Range("C1") = VList(i)
Sheets("Timesheet").PrintOut
Next
This also works, but only 1 page gets printed out.
Date also gets converted to "13 Jan 1900".
The first code does not work because it is not considering the whole range of dates; instead it takes only the value inside the first and last cell, treating them as dates. The code basically takes those dates and covers each day between them. It does not even akwnoledge the others cells between A2 and A10. This one should work:
Sub PrintAllDates()
'Declaring variables.
Dim RngDate As Range
Dim RngDates As Range
Dim RngTarget As Range
'Setting variables.
Set RngDates = Sheets("Pay Periods").Range("A2:A10")
Set RngTarget = Sheets("Timesheet").Range("C1")
'Covering each cell in RngDates.
For Each RngDate In RngDates
'Changing RngTarget.
RngTarget = RngDate.Value
'Printing RngTarget's sheet.
RngTarget.Parent.PrintOut
Next
End Sub
I've also added a feature to check if the given value is a date in this version:
Sub PrintAllDates()
'Declaring variables.
Dim RngDate As Range
Dim RngDates As Range
Dim RngTarget As Range
'Setting variables.
Set RngDates = Sheets("Pay Periods").Range("A2:A10")
Set RngTarget = Sheets("Timesheet").Range("C1")
'Covering each cell in RngDates.
For Each RngDate In RngDates
'Checking if RngDate does not contain a date value.
If Not VBA.Information.IsDate(RngDate.Value) Then
'Asking what to do in case RngDate does not contain a date value.
Select Case MsgBox("Range " & RngDate.Address(False, False) & " in sheet " & RngDate.Parent.Name & " contains the value """ & RngDate.Value & """, which is a non-date value." & vbCrLf & _
vbCrLf & _
vbCrLf & _
"Do you wish to use it and print anyway?" & vbCrLf & _
vbCrLf & _
"Press ""Yes"" to print it anyway." & vbCrLf & _
vbCrLf & _
"Press ""No"" to not print it and proceed to the next value." & vbCrLf & _
vbCrLf & _
"Press ""Cancel"" to stop the macro and print no more.", _
vbYesNoCancel, _
"Non-date value detected" _
)
'If "Cancel" is pressed, the macro is terminated.
Case Is = 2
Exit Sub
'If "Yes" is pressed, the macro goes on.
Case Is = 6
'If "No" is pressed, the macro goes to NextRngDate
Case Is = 7
GoTo NextRngDate
End Select
End If
'Changing RngTarget.
RngTarget = RngDate.Value
'Printing RngTarget's sheet.
RngTarget.Parent.PrintOut
'Checkpoint.
NextRngDate:
Next
End Sub
Your code can be something like this:
Sub PrintAllDates()
Dim listRange As Range ' Your range A2:A10 in "Pay Periods" sheet '
Dim oCurrentCell As Range ' Single cell from this range '
Dim printedSheet As Worksheet ' Target sheet - "Timesheet" '
Dim oTargetCell As Range ' C1 - target cell (to set next date from list) '
Set listRange = Worksheets("Pay Periods").Range("A2:A10")
Set printedSheet = Worksheets("Timesheet")
Set oTargetCell = printedSheet.Range("C1")
For Each oCurrentCell In listRange.Cells
oTargetCell = oCurrentCell
Rem If some cells in "Timesheet" has formulas which reffered to C1,
Rem we need recalc it before printing
printedSheet.Calculate
printedSheet.PrintOut
Next oCurrentCell
End Sub

How to make exceptions in a copy of a row

I'm beginner at Macros I need to do a copy of rows but I have to exclude some columns. EntireRow is working but I need to exclude the columns I,G,H
Sub Macro1()
Dim RngToChk as Range, RngToPaste as Range
Set RngToCheck=Application.InputBox(Prompt:="enter range", Type:=8)
Dim strtofind as String
Inttofind=InputBox("Give your Indicator")
Dim i as long
For i = RngToChk.Rows.Count To 1 Step -1
If RngToChk(i).value=strtofind Then
RngToCheck(i).Offset(1).EntireRow.Insert
Set RngToPaste=RngToChk(i).Offset(1)
RngToPaste.EntireRow.Value=RngToChk(i).EntireRow.Value
RngToPaste.EntireRow.Font.Color=RGB(255,0,0)
End If
Next i
End Sub
Add this function to your module:
Function AlmostEntireRow(StartingPoint As Range) As Range
Dim Row As Long
Dim TargetSheet As Worksheet
Row = StartingPoint.Row
Set TargetSheet = StartingPoint.Worksheet
Set AlmostEntireRow = Union(TargetSheet.Range("A" & Row & ":F" & Row), TargetSheet.Range("J" & Row & ":GR" & Row))
End Function
When you are using it, replace
RngToPaste.EntireRow.Font.Color=RGB(255,0,0)
with
AlmostEntireRow(RngToPaste).Font.Color = RGB(255, 0, 0)
and so on.
The function builds a range from the input range, consisting of columns A to F and J to GR. Adjust as needed.
Update
The suggested method does not work when copying rows. Here is a copy method as well.
Sub CopyAlmostEntireRow(FromRow As Range, ToRow As Range)
Dim FromRange As Range
Dim ToRange As Range
Set FromRange = FromRow.Worksheet.Range("A" & FromRow.Row & ":F" & FromRow.Row)
Set ToRange = ToRow.Worksheet.Range("A" & ToRow.Row & ":F" & ToRow.Row)
ToRange.Value = FromRange.Value
Set FromRange = FromRow.Worksheet.Range("J" & FromRow.Row & ":GR" & FromRow.Row)
Set ToRange = ToRow.Worksheet.Range("J" & ToRow.Row & ":GR" & ToRow.Row)
ToRange.Value = FromRange.Value
End Sub
' Call with something like this:
CopyAlmostEntireRow RngToChk(i), RngToPaste

How to select columns through VBA when the columns selectin reference is: A,E,D,S

I'm requesting a parameter from the user to specify columns (in Excel) to select, but am having some issues with converting the value to a string that I can use in VBA for reference.
I'm trying to avoid having the user enter A:A,E:E,D:D,S:S and instead just enter A,E,D,S in a cell. I'm sure the answer is right there but at the moment it's escaping me. Any suggestions?
Like I said,
Split on the , and iterate through the resultant array and build the range:
Sub fooooo()
Dim str As String
Dim rng As Range
Dim strArr() As String
str = "A,E,D,S" 'you can change this to the cell reference you want.
strArr = Split(str, ",")
With Worksheets("Sheet1") ' change to your sheet
Set rng = .Range(strArr(0) & ":" & strArr(0))
For i = 1 To UBound(strArr)
Set rng = Union(rng, .Range(strArr(i) & ":" & strArr(i)))
Next i
End With
Debug.Print rng.Address
End Sub
You can always turn this into a Function that returns a range:
Function fooooo(str As String, ws As Worksheet) As Range
Dim rng As Range
Dim strArr() As String
strArr = Split(str, ",")
With ws ' change to your sheet
Set rng = .Range(strArr(0) & ":" & strArr(0))
For i = 1 To UBound(strArr)
Set rng = Union(rng, .Range(strArr(i) & ":" & strArr(i)))
Next i
End With
Set fooooo = rng
End Function
Then you would call it like this from any sub you need:
Sub foofind()
Dim rng As Range
Dim str As String
str = "A,E,D,S"
Set rng = fooooo(str, Worksheets("Sheet1"))
Debug.Print rng.Address

How to get the address of a range with multiple subranges, including the sheet name in EACH subrange?

With the union statement I created a range existing of multiple subranges, of Worksheet("data"). I need that range for calculations on another worksheet, Worksheet("weekly"). Therefore I want the address of the range including the sheet name in each subrange. rRng is my range existing of several subranges.
rRng.Address(External:=True) returns: "data!$D$1570:$D$1575,$D$2992:$D$3000,$D$5979:$D$5988"
However, to calculate the average of the cells in this range I need: "data!$D$1570:$D$1575,data!$D$2992:$D$3000,data!$D$5979:$D$5988"
The only solution I found so far is:
Dim range_string As String
range_string = ""
Dim SubRange As range
For Each SubRange In rRng
range_string = range_string & SubRange.Address(External:=True) & ","
Next SubRange
range_string = Left(range_string, (Len(range_string) - 1))
Worksheets("weekly").range("$C2").Formula = "=AVERAGE(" & range_string & ")"
There must be a more easy way. Any suggestions?
Kind regards,
Sandra
Each of those subranges is called an Area. You can loop through the Areas of a range and build the string. Here's an example.
Sub test()
Dim rng As Range
Dim rArea As Range
Dim sForm As String
'union the ranges
Set rng = Sheet1.Range("D1570:d1575")
Set rng = Union(rng, Sheet1.Range("D2992:d3000"))
'loop through the areas and build the string
For Each rArea In rng.Areas
sForm = sForm & rArea.Address(, , , True) & ","
Next rArea
'remove the last comma
sForm = Left$(sForm, Len(sForm) - 1)
'insert the formula
Sheet2.Range("A1").Formula = "=AVERAGE(" & sForm & ")"
Debug.Print Sheet2.Range("A1").Formula
End Sub
The debug.print produces:
=AVERAGE(data!$D$1570:$D$1575,data!$D$2992:$D$3000)

how to pass the active cell value to the URL in vba excel code

This is my code
Private Sub Send_Click()
Dim cell As Range, Rng As Range
Dim strURL As String
Set Rng = Selection
For Each cell In Rng
strURL = "http://xxxxxxxx.com/excelAPI.php?customer_id=1&mobilenumber=" _
& cell.Value & "&message=" & cell.Offset(0, 1).Value
Call Sheets("Sheet1").WebBrowser4.Navigate(strURL)
Next cell
Set Rng = Nothing
End Sub
i am Highlighted only 3 mobile number in cell A and i click the button it takes only the last number.
Probably easiest to build the string first:
Dim strURL as String
strURL = "http://xxxxxxx.com/excelAPI.php?customer_id=1&mobilenumber=" _
& ActiveCell.Value & "&message=" & ActiveCell.Offset(0,1).Value
Call Sheets("Sheet1").WebBrowser4.Navigate(strURL)
Assuming the active cell contains the mobile number and the cell to it's immediate right contains the required message, otherwise specify the cells:
Dim strURL as String
strURL = "http://xxxxxxx.com/excelAPI.php?customer_id=1&mobilenumber=" _
& Range("A1").Value & "&message=" & Range("B1").Value
Call Sheets("Sheet1").WebBrowser4.Navigate(strURL)
You may need to qualify your range worksheets.
EDIT
As requested in comments to cycle through selected cells:
Dim cell As Range, Rng As Range
Dim strURL as String
Set Rng = Selection
For Each cell In Rng
strURL = "http://xxxxxxx.com/excelAPI.php?customer_id=1&mobilenumber=" _
& cell.Value & "&message=" & cell.Offset(0,1).Value
Call Sheets("Sheet1").WebBrowser4.Navigate(strURL)
Next cell
Set Rng = Nothing
Only select the cells that contain the mobile numbers, otherwise the code will try to send to the messages as well. You may want to write in some check to ensure the cell contains a number such as:
If IsNumeric(cell.Value) Then
Or a more detailed format check depending on what you have in the columns of the worksheet.

Resources