vba offset with reference to cell - excel

I need to copy a column of data to another column on a different worksheet, pasting values only. The appropriate paste column is identified in a single cell. This cell will be changed manually each time the macro is applied. So one time I might want to copy/paste in the first column, so my identifier cell is 1. The next time I might input 5 in this cell so that I offset 5 columns to the right to copy/paste data. Thank you.

You can reference the columns in a worksheet using the Columns property. You can achieve what I think you're trying to do with code like this.
Dim col As Integer
col = SomeSheet.Cells(1,1).Value
FromSheet.Columns(col).copy
ToSheet.Columns(col).PasteSpecial xlPasteValues

Related

excel countif entire row in a table

I have a structured table in excel 2016.
I want to have a cell to count the number of cells across the entire row within the table if it matches my criteria.
I have tried putting this formula in column A on each row =COUNTIF(Table[#],"my criteria") but that does not count properly.
However, this works: =COUNTIF(Table[#[ColB]:[ColH]],"my criteria"). But since my table will expand, I don't want to specify the column name [ColB], I want to refer to the entre row in the table.
A header
countif
colC
colD
colE
First
formula
A
C
Second
formula
B
C
formula = =COUNTIF(Table[#],"A") does not work
formula = =COUNTIF(Table[#[colC]:[colE]],"A") works
My table will expand both horizontally and vertically.
Please Note: This solution is only available if you chose to use VBA. VBA does not work in web versions of Excel. Please ensure that you resave your workbook as a macro-enabled workbook before proceeding.
You can choose to use VBA and create your own custom worksheet formula. Since this question didn't start out as a VBA issue, I will be a bit more detailed on the process of setting this up as opposed to just throwing you some code and you having to figure out what to do with it.
After you've re-saved your workbook as a macro-enabled workbook, open the VBA Editor (VBE) by pressing Alt and F11 simultaneously.
In the VBE, click Insert > Module. You should now see Module1 highlighted on the left side bar (The project Explorer).
Copy and paste the following code in the blank area of the module:
Option Explicit
Public Function GetMyRowCount(Criteria As Variant) As Long
Dim ws As Worksheet
Dim tblRng As Range, RowRng As Range
With Application.Caller
Set ws = .Worksheet
Set tblRng = ws.Range(.ListObject.Name)
Set RowRng = ws.Range(ws.Cells(.Row, .Column + 1), ws.Cells(.Row, tblRng.Columns.Count))
End With
GetMyRowCount = Application.WorksheetFunction.CountIf(RowRng, Criteria)
End Function
Now use this UDF (User Designed Function) in your worksheet. In the column you would like the calculation to be in, simply type =GetMyRowCount("My Criteria") and it should calculate.
To point out how this code works in more detail:
Application.Caller is referring to the cell that this function is located in. Because we now know the location of the cell, VBA can use it's location to obtain the row data from it (which is why you don't need an argument for the row #).
RowRng is getting the starting point of the column within the ws.Range(...) function with the first ws.Cells(...) function. .Row is the row # from the GetMyRowCount function (using Application.Caller.Row method), and the 3 is simply the static column C.
The way we grab the last column we need is by counting the total # of columns within the table: ws.Cells(.Row, tblRng.Columns.Count)
Using the information we obtained from bullets 2 and 3, we can establish the entire range of the lookup we need, and then place this range into your CountIf() function, along with the criteria you passed with the function's argument:
GetMyRowCount = Application.WorksheetFunction.CountIf(RowRng, Criteria)
As you can see in the following example, I wanted to count the number of times in the row the number 1 occurred:
Another example showing it works with text as well by using "Apple" as the criteria:
Try this: =COUNTIF(B:B,"my citeria"), so if your Column is A, range would be A:A, for B it is B:B.
Let me know if this helps.

How can I make a macro to copy an entire column but change a single row number?

I have inherited a poorly designed workbook, and I am trying to make it work a bit better without starting from scratch.
The last problem I have is that I have a formula in a column that I need to copy to the next column, but change the row number referenced in the formula. The easiest thing to do would be to change the format of the workbook but that will cause an uprising by the users.
=IF((CommaSeparatedListContains(RTM!$I$8,ROW()-2))=TRUE,"X","")
The code above is what I need to copy, but I need to change it so that it looks at I9 instead of I8. RTM is the name of the sheet that the cell is on, and CommaSeparatedListContains is a macro that will return true if the referenced cell has a value (ROW()-2) in the comma delimited list.
Basically I need a macro to add a new column to the worksheet that works like the others, so that the end users who don't know how to use Excel can just click a button and add a column.
For example, that code is in cell A1, and I need to move it to B1 keeping the I the same but increment the row number. If I remove Both $ signs it would change it to J8, if I have $I8 it stays I8, and if I have $I$8 it stays I8.
Thanks for re-affirming my understanding. I'll give this a shot with providing some code, based on your string:
Dim LC as Long, i as Integer
Columns(9).Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Cells(1,10).Value="" 'Add your header
LC = Cells(1, Columns.Count).End(xlToLeft).Column
i = LC-1 'See description below code
Range("J2:J100").Formula="=IF((CommaSeparatedListContains(RTM!$I$" & i & ",ROW()-2))=TRUE,""X"","""")"
For i, you want to ensure that you substract the correct number... given the example of I8 being the cell you want to reference, and assuming that Column I is the last column of your sheet, then the 9th column, 8th row, is the cell you want to reference. So, the variable i = last column - 1, in this example.
In this case, the column is always added to the right of column I, the assumed last column in the sheet.
One other assumption is that you're using rows 2 to 100 for the range that you have the formula... So, Range("J2:J100").Formula will be affected by your actual range for the formula.

Excel: How to refer to entire column in a formula by column title?

I want to write a formula like =SUM(tab2!A:A) but instead use the column title of A which is say "count". How can I modify this to look more like: =SUM(tab2!"count")?
The reason I want to do this is because I copy and paste a spreadsheet from another source in tab2 and the column referring to "count" may be in a different column. I want the formula to give me the correct calculation as soon as I paste the new spreadsheet by automatically finding the column to sum up by title name.
I must be missing something because this seems like a very basic question and I can't find the answer anywhere...
Thanks for your help!
I like the idea of naming ranges proposed by #Doug, but if the issue is that you are dumping your data in [and you don't know in advance which column is going to be where] and would need to rename your range every time, there are other options - I suggest using OFFSET. OFFSET allows you to dynamically create a range, starting at a particular point and moving down/up / right/left for as many rows and columns as you determine.
In your case, you will need to combine that with a method for searching the columns to see which one says "Count". I am assuming that your column headings are always in row 1. If they aren't [or if they aren't always in row 2, or any row you know in advance]... you can get around that but then I'd recommend you try to make your data more uniform instead of creating unnecessary Excel workarounds.
In total your formula would look like this:
=SUM(OFFSET(A1,,MATCH("Count",1:1,0)-1,ROWS(A:A),1))
What this does is first determine which column the word "Count" is found in, in row 1. Then it subtracts 1 from that number - this now equals the number of columns to the right that it is, from column A. It uses offset to create a reference to that column, for all rows, and sums those rows together.
Check out the name manager for naming ranges :)
You didn't say whether you would consider a macro solution. If so, this may work.
If the sheet you are pasting into is Sheet2 and the sheet you want the result in is Sheet1, then this macro, if placed in the Worksheet_Activate event of Sheet1 will give you the result as soon as you click on the Sheet1 tab afetr pasting your data into Sheet2:
Private Sub Worksheet_Activate()
Dim r As Range
Dim rCol As Range
Dim rFound As Range
Dim ws As Worksheet
Dim lTotal As Long
Set ws = Sheet2
Set r = ws.Cells
Set rFound = r.Find("count")
If Not rFound Is Nothing Then
Set rCol = rFound.EntireColumn
lTotal = Application.WorksheetFunction.Sum(rCol)
End If
Cells(1, 1) = lTotal
End Sub
It does assume there is only one cell with the word "count" in it on Sheet2.

Excel: delete entire row when other cell equals a defined value

I have seen (searched) similar examples, but not quite what I am looking for.
I have a Workbook in Excel that has several sheets, Sheet A and B. These sheets have a bunch of data, so in order to display the most significant data on Sheet B from Sheet A, I want to mirror only the rows that I want to specify depending on the cell values on SheetA....I need to delete entire rows in Sheet B depending on the value in Sheet A.
For instance, in Sheet A I have column X with 10 values (Yes/No), and I have linked the same data with formulas back to Sheet B. That is, that if in SheetA X1="Yes", then SheetB cell Y1="Done"...if SheetA X2="Yes", then SheetB cell Y2="Done"...if SheetA X3="No", then SheetB cell Y1="Missing"..and so on.
So I only want the rows in SheetB with cell values="Done" to be there and thus want rows with cell values="Missing" to be automatically deleted. In this fashion, I would be creating a table that only includes the rows with "Done" values for the specified cell.
I know there are macros in Excel, but I have never written code in VBA, and the language handlers and variables escapes me entirely.
Is there a way to write a macro that can be called with in a formula; that is, e.x) if(A10="Yes", "", delete row macro here)???
Thanks!
From the wording in your question it seems you want to create a function that can be used in a cell that will alter other cells. That cannot be done. The functions, when used in a formula, are limited to changing the cell itself, and not other cells.
More then one way to skin a cat. Like Abe said you can`t use formula to alter other cells. But you can use VBA. The below sub removes entire rows where the cell in range is equal to 1. But you can make it equal to whatever you want.
Sub DeleteRows()
Dim FoundCell As Range
Set FoundCell = Worksheets("SheetB").Range("YourRange").Find(what:=1)
Do Until FoundCell Is Nothing
FoundCell.EntireRow.Delete
Set FoundCell = Worksheets("SheetB").Range("YourRange").FindNext
Loop
End Sub
Of course this is extra work. What you should do instead of copying the data from A to B and then processing it, just copy the done cells from A to B.

Excel 2007 - Formula changes to #REF

So I've got this Workbook which contains a lot of data. And I've got this one sheet which basically copies the data based on certain conditions.
Each cell in each row looks like this (the last specified cell is the one where the formula is in):
=IF(Numbers1!E2<>0;Numbers1!A2;"")
=IF(Numbers1!E3<>0;Numbers1!A3;"")
=IF(Numbers1!E4<>0;Numbers1!A4;"")
=IF(Numbers1!E2<>0;Numbers1!B2;"")
=IF(Numbers1!E3<>0;Numbers1!B3;"")
=IF(Numbers1!E4<>0;Numbers1!B4;"")
So the formula in cell A2 is the first one, formula in A3 is the second line etc.
I want to copy the value from the same column and row from the sheet Numbers1, IF the value in the same row of column E is not 0. This seems to be working just fine.
But, when I update the data in Numbers1 sheet, the formulas are all of a sudden invalid and the formula now looks like this:
=IF(Numbers1!#REF!<>0;Numbers1!#REF!;"")
Each formula in each cells look identical to the formula above. And I can't have that, why can't Excel just keep the formula as it is without "helping" me?
Since you may be better off using a macro to rewrite your formulas, here are the basics:
Sub RewriteFormulas()
Dim row, col As Integer
row = 1 'row you want your target formulas to be on
For row = 1 To 60
For col = 1 To 13
ActiveSheet.Cells(row, col).Formula = "=IF(Numbers1!" & Cells(row,col).Address & "<>0,Numbers1!" & Cells(row+2,col).Adddress & ","""")"
Next row
Next col
End Sub
You can play around with using different sheets (or different workbooks) instead of just ActiveSheet so you can have 1 workbook that stores the macro and alters data in whatever workbooks provide your updated datasets.
Hope that helps...

Resources