Copy/Paste cells next to cells that have certain string - vba

I am trying to look up cells in a certain column that have a string (e.g. Names), copy the corresponding cells in the column to its right (i.e. offset(0,1) ), then paste it to a column in a different sheet. I have the following code to find the range variable that I want. However, I can't select it from a different sheet!
When I use Sheets(1).MyRange.Copy, it doesn't accept it. Am I referring to the range in a wrong way? What am I doing wrong?
Here's code that I use to get MyRange:
Option Explicit
Sub SelectByValue(Rng1 As Range, Value As Double)
Dim MyRange As Range
Dim Cell As Object
'Check every cell in the range for matching criteria.
For Each Cell In Rng1
If Cell.Value = Value Then
If MyRange Is Nothing Then
Set MyRange = Range(Cell.Address)
Else
Set MyRange = Union(MyRange, Range(Cell.Address))
End If
End If
Next
End Sub
Sub CallSelectByValue()
'Call the macro and pass all the required variables to it.
'In the line below, change the Range, Minimum Value, and Maximum Value as needed
Call SelectByValue(Sheets(1).Range("A1:A20"), "Tom")
End Sub
One More Question: Rather than specifying the exact range to look at (e.g. "A1:A20"), I would LOVE to look at all of column A. But I don't want to use ("A:A") so it wouldn't look at all rows of A. Isn't there a method to look only in cells that have entries in column A?
Thank you VERY much.
Al

You only need MyRange.Copy.
To restrict only to cells in column A which might have values, you could use
With Sheet1
Set rngToSearch = Application.Intersect(.Columns(1), .UsedRange)
End With
...or maybe look at .SpecialsCells()

Related

Highlight unique values based on another range

Column 1 is in Sheet1 and column 2 is in Sheet2. If the value is not found , then highlight that cell. I am trying to do a vlookup comparing two columns. I think the Syntax is incorrect. Please see my code I was trying below:
Option Explicit
Sub VlookupColoums()
' declarations
Dim lookFor As Range
Dim srchRange As Range
Dim I As Long
Dim vtest As Variant
' start
Set lookFor = Sheets("Sheet1").Range("A13").End(xlUp)
Set srchRange = Sheets("Sheet2").Range("A2").End(xlUp)
vtest = Application.VLookup(lookFor.Rows.Count, srchRange.Rows.Count, 2, False)
' process
For I = 1 To lookFor.Rows.Count
If IsError(vtest) Then
srchRange.Interior.Color = 4
Else
Exit Sub
End If
Next I
End Sub
Assuming you have data on Sheet1!A1:A15 and Sheet2!A1:A10.
Also assuming you want to highlight unique cells (ones withouth at least one identical in the other list) on Sheet2.
Basically you want to format all the cells that if counted on the other list comes up with 0. The steps:
Select all the cells to be evaluated on Sheet2
Go to Home/Styles/Conditional Formatting
Select New Rule, then Use a formula to determine...
Enter this formula: =COUNTIF(Sheet1!$A$1:$A$5,A1)=0
Click on the Format button, and set up a formatting for the unique cells
OK
Profit. :)

VBA Copying cells to another worksheet where cells have the same value

I have two worksheets I'm working with with long serial numbers as the cell values. One sheet (Sheet1) has a list of each individual serial number hyperlinked to a webpage referring to that item. This list ranges from A1:A31.
The second sheet (Sheet2) has a massive list of those same serial numbers, but in range G1:G102. The difference is that this list is not hyperlinked, and the serial numbers sometimes show up multiple times. There are also some areas where a cell is blank, so it splits up the continuous column of data.
I would essentially like to write a macro that takes the first list in Sheet1, and for each cell, it compares it to each cell in Sheet2 column G. Then, if the values match, I would like to copy the hyperlinked cell from Sheet 1 and paste it to that cell with the same value in Sheet2. Therefore, Sheet2 column G now has a fully populated list of hyperlinked serial numbers.
Can anyone help me with this? This is what I have so far...doesn't seem to work:
Sub CopyHyperlinks()
Dim cell As Excel.Range
Dim myRange As Excel.Range
Dim newRange As Excel.Range
Set myRange = Excel.ThisWorkbook.Sheets("Contents").Range("A1:A31")
Set newRange = Excel.ThisWorkbook.Sheets("Sheet1").Range("G1:G102")
For Each cell In myRange
If myRange.Cells.Value = newRange.Cells.Value Then newRange.Cells.Value = myRange.Cells.Value
Next cell
End Sub'
See this little function. Put this:
Function GetHyperLinkAddress(rng As Range) As String
Dim hl As Hyperlink
For Each hl In rng.Parent.Hyperlinks
If hl.Range.Address = rng.Address Then
GetHyperLinkAddress = hl.Address
Exit Function
End If
Next hl
GetHyperLinkAddress = "Not Found"
End Function
in a module. In the Spreadsheet, add
=GetHyperLinkAddress(Cell#)
Next to the cells with the hyperlink. You could then just use a vlookup to match.

Creating a dynamic range between two named cells with set number of columns

I need to create a dynamic range between two named cells (the cells and corresponding rows shouldn't be included in the selection). The number of columns is always the same (4), only the number of rows is changing. That's the first step.
Second one is putting several these ranges into a numbered list in another excel list, but that is something I can hopefully figure out myself. Thank you very much.
I might try something like this:
Sub RangeBetween()
Dim rng1 As Range, rng2 As Range
Dim betRange As Range
Set rng1 = Range("A1") 'sample data
Set rng2 = Range("A20")
Set betRange = Range(rng1.Offset(1, 0).Address & ":" & rng2.Offset(-1, 3).Address)
End Sub
This is of course assuming that your named cells are along the same column. If your named cells always spread 4 columns by default, replace the Offset(-1, 3) with Offset(-1, 0).
This code defines a named range with the name "NewNamedRange". The code assumes (and requires) that your bracketing cells are already named ranges, with the names "UpperLeft" and "LowerRight". The offset formulas exclude the bracketing cells from the named range. So if "UpperLeft" is cell D2, and "LowerRight" is cell G22, "NewNamedRange" will be the range "D3:G21". Because the named range definition is a formula, NewNamedRange will change dynamically as the bracketing cell definitions change. Hope this helps.
Sub NamedRange()
ActiveWorkbook.Names.Add _
Name:="NewNamedRange", _
RefersTo:="=OFFSET(UpperLeft,1,0):OFFSET(LowerRight,-1,0)"
End Sub

Trying to create a range from a set of values

So I have a range of cells that contains a list of Cell Addresses.
Column B & C show where a block of information starts and ends. Column D states whether it is the start of a combination of tables, the end of the combination, or whether it's a single Table.
So basically I am having some difficulty combining the answers from B & C to form a combined range. So in the picture, Column E shows the start as A170 and the End as A596. (I don't think this is necessary tbh) I need to make a range containing A170:A543, A548:A554, etc. and it needs to be dynamic. So these should create themselves based on the values in Column D. I'm looking to do this in VBA, but if it's easier to do in Excel Formulas, that's okay too.
Can anyone give me some hints how to accomplish this? My brain is currently mush.
You can create a small User Defined Function (aka UDF) that will stitch together the non-contiguous cell ranges from textual representations of their respective addresses. This can return a range for a native worksheet function that uses a cell range like the SUM function or COUNTA function (to use two very simple examples).
Function makeNoncontiguousRange(startRNGs As Range)
Dim rng As Range, rUNION As Range
For Each rng In startRNGs
If rUNION Is Nothing Then
Set rUNION = Range(rng.Value2, rng.Offset(0, 1).Value2)
Else
Set rUNION = Union(rUNION, Range(rng.Value2, rng.Offset(0, 1).Value2))
End If
Next rng
'Debug.Print rUNION.Address
Set makeNoncontiguousRange = rUNION
End Function
The function could be used on a worksheet like,
=SUM(makeNoncontiguousRange(B2:B4))
In your data sample this would be like writing,
=SUM($A$170:$A$543,$A$548:$A$554,$A$558:$A$566)
Note that I am only passing in the start of the range in column B and gaining the end range with .Offset. If you need to expand the functionality to pass in the end range then you will need to check if both the start and end ranges are the same size.

Finding average of selection and then assigning it to a cell

I am attempting to create some dynamic code that, at this point, will select a bunch of cells, move the selection over two columns, then find the average of that selection and send that value to a cell. This is what I have so far, I am getting stuck at averaging the selection I've made:
Sub StatMakersub(Rng1 As Range)
Dim MyRange As Range
Dim Cell As Object
Dim InQuestion As Range
Dim SelAvg As Object
'Check every cell in the range for matching criteria.
For Each Cell In Rng1
If Cell.Value = 2000 Then
If MyRange Is Nothing Then
Set MyRange = Range(Cell.Address)
Else
Set MyRange = Union(MyRange, Range(Cell.Address))
End If
End If
Next
'Select the new range of only matching criteria
MyRange.Select
Selection.Offset(0, 2).Select
Set InQuestion = Selection
Range("P2").Formula = "=Average(Selection)"
Range("Q2").Formula = "=STDDEVA(Selection)"
End Sub
I can't find much on the web about how to average range variables.
You can calculate the average of a selection in this way:
Application.WorksheetFunction.Average("Here you put your range")
The result is a value and not an object, so you should use a variable. Taking names from your case you should use it like this:
SelAvgResult = Application.WorksheetFunction.Average(InQuestion)
I put another name for the variable, but you may still use SelAvg if you like. Just remind to define it as a variable (you may choose your desired format depending on the data size) instead of object if you do not need it anymore.
You may use then this variable for setting the value of your desired cell.
I have a last note: your code seems to replicate the already existing formula AVERAGEIF. If your criteria column is for instance column A and value you should use for calculating the average are in column C, You could directly set the value of the cell where you want the average like this:
=AVERAGEIF(A:A, "2000", C:C)
In this case you would avoid VBA.
Have you tried using the Sum worksheet function for calculating the sum of the range?
Xsum = WorksheetFunction.Sum(arrayX)
and dividing the Xsum value with the length of the array?
One thing I should metion is that you do not need to select the range to work with it. You can use it directly and doing so will also improve how fast your code runs.
To insert your worksheet functions, use the Range.Address function to generate a cell reference to put into the formulas.
https://msdn.microsoft.com/en-us/library/office/ff837625.aspx