I have multiple sheets in excel that all have a "Name" column. I want a list with all of these combined, without duplicates. A pivot-table cannot do it from my understanding, and when trying this http://www.cpearson.com/EXCEL/TableToColumn.aspx, I only get results from column A:A. The example however, suggest that A:A, B:B, C:C should be combined in D:D when I name D:D "ColumnData" and the table "DataTable" (the naming doesn't seem to be wrong, since I get some result).
Any help? This is the code I use and have put in D2 (just changed commas to semicolons for the local of my Excel):
=OFFSET(DataTable;
MOD(ROW()-ROW([ColumnData]);ROWS(DataTable));
TRUNC((ROW()-ROW([ColumnData]))/ROWS(DataTable));1;1)
Additional info:
First I have pivot-tables to make a list without duplicate names from my sheets (as they consist of a lot of data). Then I have a name for it (name manager) with the formula:
='Name lists'!$A$2:INDEX('Name lists'!$A:$A;MATCH("*";'Name lists'!$A:$A;-1);1)
..and call that "NamesSheet1" for example.
I then populate A:A in my table with:
=IFERROR(INDEX(NamesSheet1;MATCH(NamesSheet1;NamesSheet1;0));"")
..and drag that formula down to more rows than there are names. Then I repeat for each new column, B:B, C:C.
Rename a new tab in your workbook as Master. and run the below code.It will copy all the data in different tabs to Master tab. let me know if this is what was required or any other changes required.
Sub ttest()
Dim wb As ThisWorkbook
Dim ws As Object
For Each ws In ActiveWorkbook.Worksheets
ws.Select
ActiveSheet.UsedRange.Copy
Worksheets("Master").Select
i = Range("A65536").End(xlUp).Row
Range("A" & i+1).Select
ActiveSheet.Paste
Next
End Sub
I fixed it to my satisfaction by going with the "ColumnDataR"-option from the linked example, and then making a pivot-table from THAT column (as the "ColumnDataR"-column did not remove duplicates. Then I made a NEW name list (name manager) based on the new pivot-table. A bit of a long way around it, though now I just need to enter my Raw Data into the sheets, then refresh all data.
Related
I would like to run a macro that finds columns based on the header strings in a Source Workbook, copies the visible rows below the header, and pastes into a different Master workbook in a specified column location.
There are about 5 specific columns I need to copy data from, for example "Part Name", "Part Number", "Vendor", ect. I need to use string values because where I am pasting the values on the master workbook has different headers. "Part Number" on the source workbook might translate to "Part #" on the Master workbook.
I have tried the code below, and it works but it is very slow, and this is just for 1 column.
Any ideas how to clean up this code and make it run more smoothly and quickly?
Thanks!
I have tried calling an Optimize function that turns of screen updating, automatic calculations, ect.
Sub Import()
Call Optimize
Dim source As String Dim dest As String
'Clears the Table Call CleanTheTable
source = Worksheets("Set-Up").Range("B11") '<=== Source workbook based on cell value
dest = Worksheets("Set-Up").Range("B8") '<=== Destination workbook based on cell value
'------------ Header Value to Look Up -------------
Workbooks(source).Worksheets("Source Sheet").Range("Table1[Value to Look Up]").SpecialCells(xlCellTypeVisible).Copy _ Destination:=Workbooks(dest).Worksheets("INPUTS1").Range("A2")
End Sub
Personally, I would avoid using the copy method altogether. It's ridiculously slow because it will copy formatting as well. If you don't need the formatting copied, then I'd just equate the cells directly:
TargetSheet.cell.value = SourceSheet.cell.value
This is typically much faster than using the .copy method.
I hope this helps.
I'd like to be able to retrieve values from an Excel table by row number and column name (for code readability and robustness).
In formulas, I can use Structured References with column header text and get a value from the table like this:
=INDIRECT(ADDRESS(<absolute_line_number>;COLUMN(<table_name>[<column_name>])))
This is robust for formulas because if the user renames the column, all Structured References to it in formulas will be automatically updated.
Not so for VBA code though.
For worksheets, it's possible to define Worksheet.CodeName for use in VBA code that will stay the same if the user renames the visible sheet name.
No such property exists for an Excel table AFAICS.
The best idea I currently have is to make table headers 1-cell Named Ranges. Then I can get a value from a table in VBA like this:
<sheet_codename>.Cells(<line_number>,Range("<range_name>").Column)
This, however, bothers me because Named Ranges are disconnected from the table. E.g. if I rearrange tables on the sheet, the ranges will remain in the old place.
Is there a better option? "Better" means specifically:
Survives renaming and/or rearranging columns in the table, moving the table at least within the sheet
Comment
A comment in each header cell of a ListObject remains there, if the column is renamed or rearranged.
If(!) you can hide all comments by Application.DisplayCommentIndicator = xlNoIndicator (all comments neither recognisable by red triangle nor visible during mouseover), this may be a workaround:
Private Sub RecognizeColumnsOfListObject()
Dim lo As ListObject
Dim lc As ListColumn
For Each lo In ActiveSheet.ListObjects
For Each lc In lo.ListColumns
Debug.Print lc.Index ' not unique, always 1, 2, 3, ...
Debug.Print lc.Name ' not unique, changeable
If Not lc.Range.Cells(1).Comment Is Nothing Then
Debug.Print lc.Range.Cells(1).Comment.text ' unique
End If
Next lc
Next lo
End Sub
Named Range
If I give each header cell of a ListObject a name, it moves with the column if I rearrange the ListObject. As its Name.Value or Name.RefersTo begins with =<ListObjectName>... I get the absolute address by this:
Dim n As Name
With <sheet_codename>
For Each n In .Names
Debug.Print .Range(Mid(n.RefersTo, 1)).Address
Next n
End With
On closer inspection, there's nothing wrong with making table headers Named Ranges. That's because such Names get assigned to a Structured Reference rather than raw cell address, so they will move around together with the column!
On the downside, this name is not printed in the address field (at least, in Office 2007) when selecting the header which is rather inconvenient ('cuz I can't quickly look up the name I should type into the code to get this column).
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.
I have a problem with a VBA script. I guess the solution is simple, but I just wasnt able to figure it out....
So basically, I have a workbook that contains many worksheets. Each worksheet contains the exact same format of a table (same number of rows and columns). What I wanted to do was to create a new worksheet and in that worksheet, have averages of all those values.
So for example in cell B2 I want to have average of cells B2 from all the other worksheets. I therefore created a macro that does this, this is not a problem, the problem is however, that in that macro, all sheets are referred to by their names and since I have many of these workbooks with differently named sheets, this would not work. I therefore tried to change the name of the first sheet to actual reference of sheet - i.e. Sheet(1) and the last one as Sheet(x) - where x is the number of sheets I calculated previously. Unfortunately the code doesnt work, could anyone please suggest to me how to modify this so that it works properly? I am only copying the problematic part of the code:
x = Sheets.Count
Sheets.Add After:=Sheets(x)
Range("B2").Select
ActiveCell.FormulaR1C1 = "=AVERAGE(Sheets(1):Sheets(x)!RC)"
Try this. You are not offseting your sheet names (in fact, you're not even using the sheet names. In the context of a formula, Sheets(1) is meaningless. You need to use Sheets(1).Name and offset it appropriately:
"=AVERAGE('" & Sheets(1).Name & ":" & Sheets(x).Name & "'!RC)"
I have a spreadsheet that has a tab for each research location. There is a section on the sheet that has several columns. Three of the columns are as follows: 1 lists action items (text) 1 lists who is responsible (text) and 1 lists the due date (date field). The rows in this same "table" represent categories. In many cases there is an action item only in one or two categories or maybe none at all for some.
I would like to query each tab that represents a research site and pull any action items, the responsible party and date onto another tab so that we can see all action items in one place for all the sites vs. going tab by tab to review.
I thought some sort of IF or VLOOKUP function might work, or some sort of pivot table but because it is text and not numbers I am having a hard time crafting the appropriate formula. I was also told I could do some sort of reference look up (like putting a word like ACTION at the start of any text I want to find later) but this seems more complicated than it needs to be.
Any help would be deeply appreciated.
I don't think VLOOKUP can solve your problem. You definitely need VBA so something like this will get you going. Make a new sheet called as Summary and put this code in the sheet:
Sub SummarizeSheets()
Dim ws As Worksheet
Application.ScreenUpdating = False
Sheets("Summary").Activate
Range("A2").Select
For Each ws In Worksheets
If ws.Name <> "Summary" Then
If ws.Range("A2") <> "" Then 'A2 is blank means no action items found so go to next worksheet
ws.Range("A2:C100000").Copy 'Adjust your range here
ActiveSheet.Paste Range("A65536").End(xlUp).Offset(2, 0)' Paste the copied range
End If
End If
Next ws
Application.CutCopyMode = False
End Sub
You have to adjust the code to suit your needs. Assumption here is your action items starts with cell A2 and responsible person and due date are in cell B2 and C2 respectively.