copy selected row cell entries to other sheet - vba

I'm trying to provide the capability to select either a row or column in a row and copy certain cells off the row into a different sheet.
For example...I have a list of renters (rows) each with the amount they owe and the amount collected on one sheet and the other sheet is a receipt. I'd like to enter the rent collected and have the receipt sheet updated automatically with the other sheets rows/individuals name and amount collected.
Is there a VB function to identify the active row?
If I can get that working the next thing would be adding/incrementing the invoice number.

You can use a combination of UsedRange and the Rows() property to get your active row.
While UsedRange is not necessarily required, it would only select the used cells in that row as opposed to selecting the entire row of the workbook, which is very likely unneeded.
You can use this function:
Function rngActiveRow() As Range
Dim ws As Worksheet
Set ws = ActiveCell.Parent
Set rngActiveRow = ws.UsedRange.Rows(ActiveCell.Row)
End Function
If you wanted to test it, you can try calling this function in a test sub to see it work:
Sub test()
rngActiveRow.Select
End Sub

Related

Variable Named Ranges in Excel

I have a table in Excel formatted as follows:
Date Asset Return
1/3/2005 0.003582399
1/4/2005 -0.01908258
1/5/2005 0.002080625
1/6/2005 0.005699497
1/7/2005 -0.008040505
1/10/2005 -0.00339116
1/11/2005 -0.009715187
1/12/2005 0.002371855
1/13/2005 -0.00580783
1/14/2005 0.001058481
1/18/2005 0.015483842
1/19/2005 -0.014690715
1/20/2005 -0.015714799
1/21/2005 -0.010796326
I need a named range to reference each column. The workbook is a template, so the named range won't always cover the same number of rows depending on the data. I want to set it so that the named range "Date" and the named range "Asset Return" are automatically sized to cover the entire column from the first value until the last, without going past the last value in the column.
It will always start at cell B8, but might end at a different row depending on the size of the data.
How can I set a dynamic named range to accomplish this?
This named range formula will do it:
=Sheet1!$B$8:INDEX(Sheet1!$B:$B,COUNTA(Sheet1!$B:$B)+8)
Remember to add the sheet name as the named range will operate on the active sheet otherwise.
The formula starts takes B8 as it's starting point: Sheet1!$B$8
It then counts how many cells are not blank in column B: COUNTA(Sheet1!$B:$B)
It adds 8 to the count (assuming your first rows are blank).
It then uses INDEX and the COUNTA to reference the last cell.
https://support.office.com/en-gb/article/INDEX-function-a5dcf0dd-996d-40a4-a822-b56b061328bd
https://support.office.com/en-gb/article/COUNTA-function-7dc98875-d5c1-46f1-9a82-53f3219e2509
Try this VBA code
Sub test()
application.DisplayAlerts = false
Range("B8").currentregion.createnames _
top:true, right:=false, left:=false, bottom:=false
application.DisplayAlerts = true
end sub

How to select column and display its current format using VBA Macro?

Please find my requirement below for which I am unable to find any solution:
1. Iterate over workSheet from workbook
2. Find all the columns containing date values using current format/type of column (Here is a trick. Worksheet is not static, it can contain any number of columns containing date values. Columns containing date values may have any name. And such worksheets can be more than one in number)
3. Apply macro on date columns for date formatting (below macro) if "Flag" value is "y"
<code>
Sub FormatDate()
If wksSecDist.Range("Flag").value = "y" Then
LastRowColA = Range("X" & Rows.Count).End(xlUp).Row
' Here I am finding total number of rows in column X
wksSecDist.Range("X2", "X" & LastRowColA).NumberFormat = "dd/mmm/yyyy"
' Here applying specified date format to Range("X2", "X10") [if last row index for column X is 10]
End If
End Sub
</code>
I am just a beginner to VBA.
Thanks in advance.
I suspect you didn't find a solution on the internet because you looked simply for a solution and not the parts needed to build your own solution.
You mention you are a VBA beginner, please take the below answer to be of educational use and begin you in getting you where you need your tool to be. Note, if it doesn't answer your question because of information that was not included, it has still answered your question and the missing information should form part of a new question. That said, lets get this function up and running.
From what you have written I have interpreted the requirement to be: -
Look over all worksheets in a workbook ('worksheets can be more than one in number')
Check every column to see if it holds a date value
If it does, set the whole column to a specific format
What is needed to accomplish this is iteration(loops), one to loop through all worksheet, and another to loop through all columns: -
The is pseudo code of the target: -
.For each Worksheet in the Workbook
..For each Column in the Worksheet
...If the Column contains dates then format it as required
..Process next column
.Process next Worksheet
We achieve this using a variable to reference a Worksheet and using a loop (For Each) to change the reference. The same goes for the columns.
Public Sub Sample()
Dim WkSht As Excel.Worksheet
Dim LngCols As Long
Dim LngCol As Long
'This loop will process the code inside it against every worksheet in this Workbook
For Each WkSht In ThisWorkbook.Worksheets
'Go to the top right of the worksheet and then come in, this finds the last used column
LngCols = WkSht.Range(WkSht.Cells(1, WkSht.Columns.Count).Address).End(xlToLeft).Column
'This loop will process the code inside it against every column in the worksheet
For LngCol = 1 To LngCols
'If the first cell contains a date then we should format the column
If IsDate(WkSht.Cells(2, LngCol)) Then
'Set right to the bottom of the sheet
WkSht.Range(WkSht.Cells(2, LngCol), WkSht.Cells(WkSht.Rows.Count, LngCol)).NumberFormat = "dd/mmm/yyyy"
End If
Next
Next
End Sub
Hopefully that has all made sense, this does work on the premise that the header row is always row 1 and there are no gaps in the columns, but these are separate issues you can approach when you're ready to.

How can I copy & paste entire rows with distinct values to a new sheet on varying cell ranges?

I know there's many StackOverlow Q&A's on copying & pasting from a cell value in VBA. However, I can't seem to make it work for my own project. I want to copy the entire row(s) if it matches the Distinct Store# (non incremental) in Column H into a new sheet (in this code below, "Sheet1") which already has a template layout where I copy/paste the values. The template looks the same on every sheet before any data is filled in, except the first 2 tabs which have the data ("Appointments" and "Invoices").
I came up with the VBA below, but here's the catch- the cell# that it pastes the row(s) (in the code below, "A10") changes based on the Store #. This is because I am copying rows from the 1st sheet ("Appointments") in the workbook from the distinct Store#, then deleting the empty rows above the area where the 2nd sheet ("Invoices") data goes. Some stores may return 10 rows or none at all. The Case, which is the Store #, is currently manually put in one by one. Should it be an array instead?
Anyway...I was hoping to automate the copying/pasting and loop for each store to their sheet. Maybe I'm going about this wrong, but would anyone be kind enough to suggest how to solve my error code "Method or data member not found." as well as provide any suggestions on making my code better for a loop for filtered cell copying to different spots for each sheet.
Simple explanation of my step by step process:
1.Filter Store # from "Appointments" sheet.
2. Copy all rows for that store and paste into a new sheet with template named "Sheet1" in B3.
3. Filter Store # from "Invoices" sheet.
4. Copy all rows for that store and paste into the previously made sheet named "Sheet" under the above rows. (Some stores do not have invoices, so this section is blank/NULL). Paste destination cell for "Invoices" will be different for each store# depending on how many rows they get from the "Appointments" sheet (could be A10 or A25).
5. LOOP- Next store #, next sheet (sheet2).
Sub CopyToNewSheetInv()
Dim i As Range
Dim book As Workbooks
Dim sheet1 As Worksheets
Dim sheet2 As Worksheets
Set book = Workbooks("SampleWorkbookName")
Set sheet1 = Worksheets("AllInvoices")
Set sheet2 = Worksheets("Sheet1")
For Each i In sheet1.Range("H:H")
Select Case i.Value
Case 1243
sheet2.Range("A10").End(xlUp).Offset(1, 0).EntireRow.Value = i.EntireRow.Value
Case Else
End Select
Next i
End Sub
Try this:
Sub CopyToNewSheetInv()
Dim i As Range
Dim book As Workbook
Dim sheet1 As Worksheet
Dim sheet2 As Worksheet
Set book = Workbooks("SampleWorkbookName.xlsx")
Set sheet1 = book.Worksheets("AllInvoices")
Set sheet2 = book.Worksheets("Sheet1")
'iterate only thorugh those cells in H that have data, not all 1.04 million
For Each i In sheet1.Range("H1", sheet1.Range("H" & sheet1.Rows.Count).End(xlUp))
Select Case i.Value
Case 1243,"1243"
sheet2.Rows(sheet2.Range("A10000").End(xlUp).Offset(1, 0).Row).Value = sheet1.Rows(i.Row).Value
Case Else
End Select
Next i
End Sub

VBA For Each worksheet only working on first sheet

I am creating a workbook with 17 sheets and each one has a product list that will change from month to month. If a product has errors, it shows up as CMB in the values but the product is still there. I was to delete the product rows. This code works on a sheet by sheet basis, but once I try to loop it, it does not work.
Sub wsLoop()
Dim ws as Worksheet
For Each ws In Worksheets
'Seeing if there are new products added to list
countcells = Range(Range("F8").End(xlDown).Offset(, -4), Range("A8").End(xlDown)).Cells.SpecialCells(xlCellTypeConstants).Count
'if no products added, then see if there in CMB in any row and delete that row
If countcells = 1 Then
If Not Range("E:E").Find("CMB") Is Nothing Then
Range(Range("E:E").Find("CMB"), Range("E8").End(xlDown)).Rows.EntireRow.Delete
End If
End If
Next ws
End Sub
You have to actually get the range of the current worksheet. E.g.,
countcells = ws.Range(ws.Range("F8").End(xlDown).Offset(, -4), ws.Range("A8").End(xlDown)).Cells.SpecialCells(xlCellTypeConstants).Count
Otherwise, you will always be just grabbing ranges off the currently selected worksheet (which will generally be the first worksheet).
Note that you will need to repeat this for all instances of Range.
By the way, one thing you can do to make this easier is to use With:
With ws
countcells = .Range(.Range("F8").End(xlDown).Offset(, -4), .Range("A8").End(xlDown)).Cells.SpecialCells(xlCellTypeConstants).Count
'repeat for all lines
End With
With eliminates the need to repeat the name of the object over and over. You just type .property, and it automatically knows you mean ws.property.

Excel VBA Macro

The List:- “Problem Sheet”(worksheet).
I have an excel sheet which represents a list of problem issues (Rows) which varies in size every day (eg more or fewer rows);
Each row has been assigned a name;
The assigned name is always in the same column “M” of the “Problem Sheet”;
An individual assignment name does not necessarily appear every day, or it may occur several times (on more than one row) on a given day;
I already have a macro that creates a Unique List (worksheet) of assignment names where each name appearing in column M of the Problem Sheet is recorded once in the “Unique List” worksheet;
The same macro creates a single new worksheet (in the same workbook) for every unique occurrence of an Assignment Name.
The Assignment Name is recorded automatically in the new individual worksheet tab.
Required:-
A macro that will check Column M of the main “Problem Sheet”;
For every row / problem where a particular assignment name occurs in Column M of the Problem Sheet, Match the assignment name with the worksheet of the same name, then Copy and Paste the details of the entire row from the “Problem Sheet” to the first blank row of the correct (same assigned name) worksheet in the existing workbook.
This routine must be repeated for every row in the Problem Sheet.
If order doesn't matter, this might be your best bet
Sub x()
Dim rngProbs As Range
With ThisWorkbook.Worksheets("Problem Sheet")
Set rngProbs = .Range("M1", .Range("M1").End(xlDown))
End With
Dim r As Range
For Each r In rngProbs
r.EntireRow.Copy
ThisWorkbook.Worksheets(r.Text).Rows(1).EntireRow.Insert
Next r
End Sub