Copying values across a dynamic column and row range - vba

I have the following code that:
copies the column headings (in row 1) from column C across to the second last column
pastes these column headings in row 1 in the column 2 across from the last column with data
pastes the column headings alongside each row of data through to the bottom row
Sub GLDR()
'use End(xlUp) to determine Last Row with Data, in column A of the GLDRYYPP tab
Dim lastRowDR As Long
lastRowDR = Sheets("GLDRYYPP").Range("A" & Rows.Count).End(xlUp).Row
'copy the cost type categories and paste alongside the cost centres
CTNameCol = "S2:AF" & lastRowDR
Sheets("GLDRYYPP").Range("C1", Range("C1").End(xlToRight).Offset(0, -1)).Copy
Sheets("GLDRYYPP").Paste Destination:=Sheets("GLDRYYPP").Range("C1").End(xlToRight).Offset(0, 2)
Sheets("GLDRYYPP").Range(Range("C1").End(xlToRight).Offset(0, 2), Range("C1").End(xlToRight).Offset(0, 2).End(xlToRight)).Copy
Sheets("GLDRYYPP").Paste Destination:=Sheets("GLDRYYPP").Range(CTNameCol)
End Sub
The first two steps have been set to be dynamic for any additional columns added but I am having trouble writing some code that will paste the data through to the bottom row. As you can see the range "S2:AF(last row)" has been written to make use of the result from the lastRowDR dimension.
Is there a way to write the code which will make the copy dynamic across the columns and rows?

Yes there is a way to write the code which will make the copy dynamic across the columns and rows. What you need to do is to identify a distinct quality about the cost centres so that you locate it using something like ActiveSheet.Cells.Find(Txt).
Then you'll be able to determine what CTNameCol should be. There is some helpful info here: Range.Find Method.
If you add add a picture of your spreadsheet I will update this answer with more precise information.

Related

Find number of rows in a column of a particular sheet in macros

I am struggling to write a function in VBA which takes sheet name and column as parameters and returns last used row number in that column of that sheet.
I used the following code:
Worksheet("sheetname").Range("e2").End(xlDown).Row
But it returns wrong values... like 104567
Please provide me the code to find row count in a particular column of particular sheet.
The 1 in the code is the column you would like to check. You can change ActiveSheet to any other valid worksheet object.
lLastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
An explanation: The number is actually 1,048,576 - the bottom of the worksheet. What it means is that there are no non-empty cells in the column "E:E" below row 2. The solution provided by braX is a standard and a very good way of handling this. In case you want to spec the column by name, you can do this:
Worksheet("sheetname").Range("e" & Worksheet("sheetname").Rows.Count).End(xlUp).Row

Deleting all columns between the first one and the last four on a sheet

I have a worksheet here with multiple columns full of data, ranging from cell AA to CT currently. The first column contains rows with headings and is frozen. Data is added to the end column of this range weekly. & Then all columns between the first and the last four are deleted (to show a month's worth of data but keep the headings intact).
I'm very new to VBA and I've been trying to write some code to automate this, so far I've managed to select the 5th column in from the end. But I can't get it to select the columns in between the 4th column from the end and Cell AA:
Sub DeleteColumns()
Dim i
i = Range("KFIData").End(xlToRight).Offset(0,-4).EntireColumn.Select
Columns("AA:ColumnFive").Delete
End Sub
Am I going about this completely the wrong way?
Many thanks
Well if you managed to catch column 5 from the end, use this statement:
Range(Columns("AA"), Columns(ColumnFiveFromEnd)).Delete
ColumnFiveFromEnd can be a number as well as a text identifier.

How to move parts of a dynamic pivot table to a separate table?

I have pivot table pulling data from a query from a proprietary database system we use at work. I'm trying to figure out a way to move certain parts of the pivot table to a different sheet where it wouldn't exist as a pivot table there. My problem I'm running into is that the table changes the number of columns and rows depending upon the types and amounts of things that we shipped that shift, so I can't have it simply have my new table equal the cell values in the pivot table.
This is an example of the pivot data having fewer columns and rows based on what occurred that shift at work.
The reason why I would like this in a regular table as opposed to a pivot table is because there's other calculations I'd like to put into the table that extend beyond a pivot table's capabilities (ex. have the user id be displayed as their name, and have a weighted system based off of what the driver moves, but I suppose that's irrelevant.)
I've been poking around the internet, and it seems that the majority of answers to this issue deal with static tables. Any help would be appreciated!
Let's assume you want the cell to have the value from "BEER Total" for "M307577". Then this would be the formula you put in the cell:
=VLOOKUP("M307577",A5:Z100,MATCH("BEER Total",A5:Z5,0),FALSE)
"A5:Z100" would be the whole pivot table and "A5:Z5" would be the first row containing variables.
As you mentioned you are not familiar with VBA, I would suggest this approach:
Use the first column and first row of the second sheet as a reference. Refer to all the variables from the pivot table there (refer to the cell containing IDs and Variables, and pull the formula to the last row for IDs and last column for variables (or a reasonable range as last column and row would not be sufficient)). This will leave you with zeros, empty cells from the pivot table sheet, but will have all the names that you need.
Then refer to those cells and use the aforementioned formula (instead of names, use the cells that you just created).
Whenever the pivot table updates, those cells will be updated as well and you will see the values for the corresponding ID and Variable.
I think you want the GETPIVOTDATA function. Determine what your logic will look like and click on the appropriate combination of cells. Excel will automatically setup the GETPIVOTDATA function appropriately for you.
http://www.contextures.com/xlPivot06.html
Also, if the last used columns and last used rows are changing, you will probably need a Macro to help you with your task.
Sub LastRowInOneColumn()
'Find the last used row in a Column: column A in this example
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
MsgBox LastRow
End Sub
Sub LastColumnInOneRow()
'Find the last used column in a Row: row 1 in this example
Dim LastCol As Integer
With ActiveSheet
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
MsgBox LastCol
End Sub
You can use a combination of functions to help you get the last used cell in a specific range.
https://exceljet.net/formula/address-of-last-cell-in-range
From there, I think you can figure out your next steps.
Post back with more information if you still have trouble with this, or start a new post if your question is answered.

Large Data set Macro query & alternative to Vlookup request

This query is two fold. Any assistance would be much appreciated and unfortunately there is a lot of detail behind this so apologies for the great deal of text.
I am working on updating a 12 month trending report that pulls data from one sheet using a series of complex vlookups based on several criteria (Project, unique project id, Order, yr-month etc). Yes it would likely be easier to use pivot tables, but unfortunately because of the way this document is used the people with access to it want it to remain as is, from a format and function perspective but want the document sped up (takes roughly 5 minutes to calculate when ever something is changed.)
The data set is 36 columns by 50000 rows with 7 columns containing identifiers used to pull in specific data on the trending sheet
As it current sits on a monthly basis new data (approximately 6000 rows) of additional data is added.
I've added two macros to the document in an attempt to reduce user error
I am currently using the following code to take the order number remove the duplicates and then apply an index/match to pull in the relevant Project and then use countif to apply a unique key to the end of the project (using concatenate)
Sub ProjTrending1()
Dim s1 As Worksheet, s2 As Worksheet
'Defines S1 as a Worksheet
Set s1 = Sheets("All Data")
'Defines S2 as WorkSheet
Set s2 = Sheets("Workings")
'Defines LastR1
Dim LastR1 As Long, DataRange1 As Range
'Finds last row cell working sheet
LastR1 = s2.Range("A1").CurrentRegion.Rows.Count
'Takes Data from Order Column of defined data Sheet and copy & pastes it to Working Sheet Column B
s1.Range("J1:J" & LastR2).Copy s2.Range("A1")
'Removes Duplicates from Column B Working sheet
s2.Range("A2:A" & LastR1).RemoveDuplicates Columns:=2, Header:=xlNo
'Copies the formula from B2 and applies it to all cells in column B where column A has values
s2.Range("B2").Copy s2.Range("B2:B" & LastR1)
'Copies the formula from C2 and applies it to all cells in column C where column A has values
s2.Range("C2").Copy s2.Range("C2:C" & LastR1)
End Sub
The formula is column B is as follows
=INDEX('All Data'!E:E,MATCH(Workings!A2,'All Data'!J:J,0))
The formula in column C is as follows
=B2&COUNTIFS($B$2:B2,B2)
The data set in worksheet All Data is approx 50k rows long and will continue to grow. The issue I'm not running into is that this macro is starting to take a great deal of time to run because the information in column C is used as a unique identifier on the trending report.
Is this because I have a vast number of Vlookups on the trending tab (approx 20k) pulling data based on this or is there an issue with the macro I have created to create a unique identifier?
I've been looking at alternative ways in which I could draw the data through to the trending tab (dictionaries etc) with no luck so far. It would be much appreciated if someone could offer an alternative to 20k vlookups.

Excel Autofilter, Copy selection, Paste to new sheet

I have a table with source data in columns Regions!A6:R553.
In Regions!A3:R3, I have formulas that pull specific information out of my data table in Regions!A6:R553 that I want copied to a different sheet.
Column A acts as my project name column, while column B holds ID numbers. In my case, there are multiple ID numbers per project.
I am looking for a script to filter and loop through all the unique order numbers in Column B one by one, then copy cells A3:R3 to RegionsSummary!A12:R12 for as many rows as there are unique order numbers (i.e, add rows to the table).
Here is a screengrab of my data sheet, "Regions":
i.stack.imgur.com/aTPuw.png
Here is a screengrab of the empty template sheet "RegionsSummary":
i.stack.imgur.com/9Ukz5.png
Example: Assume there are 5 projects in my data sheet. I will filter the data using another macro to select Project_1. I would then like a command button to active a macro that will filter to the first order number in Column B, copy Regions!A3:R3 to RegionsSummary!A12:R12, then filter to the second order number in Project_1, and repeat the process. This should go on until all unique ID numbers have been filtered and looped through.
Here is a screengrab of what a final product should look like:
i.stack.imgur.com/9Ukz5.png
Here is a link to the file: Final Output Example
I would go with an easier solution than a Macro with certain constraints. I am not able to access your sheet, so I will make a sample excel.
STEPS:
Create a list of unique projects for a dropdown (COPY Regions!A5:A10000 to a new sheet > Data > Remove Duplicates) . Create the dropdown (Data Validation > List > Select Range) using Data Validation in "Example_Result" sheet- C7.
In "Regions", in Col S, put the below formula
=S6&"_"&COUNTIF($S$6:S6,S6)
Copy this formula down for the entire sheet or as long as you expect the sheet to grow
In "Example_Result", insert an index column (1 to 1000, in Col A if you expect each project to have 1000 or less order numbers) from A12 onwards.
Along the columns (B onwards) of Row 11 include the names of the variables from Regions (Assessment Project, Highway etc).
Insert the below formula in B12 to S1000 (depending on number of variables) of Example_Result:
=IFERROR(INDEX(Regions!$A$5:$S$10000,MATCH($C$7&"_"&A$12,Regions!$S$5:$S$10000,0),MATCH(B$11,Regions!$A$5:$H$5,0)),"")