Copy row from one sheet and insert copied row under last row in another sheet - vba

I am in need of your expert assistance.
I am trying to write some code that will copy rows and insert the copied row below the last row in another sheet.
I have a Global sheet that has the data i will be copying. It will need to look in column Q.
I think the problem will be when trying to copy the data, the data in column G is the text name of a Contract Code. But the sheets are name with the Number version.
for example i have a row that has BRREPAIRS in column Q, I need this to copy to Sheet 2870, then i have a row that has BRVOIDS in column Q, I need this to copy to Sheet 2781.
I could have multiple different Contract names so i think i might need to define the text to equal a sheet. So maybe Set BRVOIDS = Sheet.name("2781") Set BRREPAIRS = Sheet.name("2780") and so on until all sheets are defined.
When the data gets copied i need it to find the last row in column a that has data, when it is found it will insert the copied row into the sheet. for example EntireRow.Insert Shift:=xlDown.
I dont have any code at the moment. I would really appreciate all the assistance.

You don't need to do things like Set BRVOIDS = Sheet.name("2781"). In fact, that would be positively harmful since then you would need to run the data in Column Q through a possibly large Select statement to know what variable to use. Instead, you could write a function like
Function TargetSheet(ContractName As String) As Worksheet
'code which uses your secret list to determine target sheet
'Maybe a Select statement, Maybe a Vlookup -- who knows?
Set TargetSheet = 'sheet your code determined
End Function
Sounds like your code will be scanning down column Q, determining where to copy the corresponding row to. Once you get the above function working, you could combine it with something like this:
Function LastRow(TargetCol As Variant, Optional ws As Variant) As Range
'assumes TargetCol is something like 1 or "A"
Dim n As Long
If IsMissing(ws) Then Set ws = ActiveSheet
n = ws.Cells(1, TargetCol).EntireColumn.Rows.Count
Set LastRow = ws.Cells(n, TargetCol).End(xlUp).EntireRow
End Function
This returns as a range the last row containing data (or row 1 if the column is empty) in a specified column in a specified worksheet (which defaults to the Active sheet).
You haven't given enough to go on, but something along the lines of
LastRow("A",TargetSheet(Range("Q" & i).Value)).Insert Shift := xlDown
Might be what you are looking for. Why don't you try to work it out and ask another question (if need be) once you have some actual code?

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

Excel VBA Compare cell value to list and overwrite value in separate sheet

In a workbook I have, users either manually enter an account code or select one from a list and the account codes are placed in column C (C7:C446) in a sheet called "JE". The account codes look like this ####### - ### - ## - ######. In column D (D7:D446) in sheet "JE", there is a formula that captures the last 6 digits of the account code. In a sheet called "required_refs", there is a list of 6 digit codes in column A. If the value in the D column in sheet "JE" equals any of the values in column A of "required_refs" sheet, I would like the value in the D column cell to overwrite the cell value in cell D1 in a separate sheet called "references" (I know that may have been confusing, sorry)
Example: if the value of D25 matches any of the values listed in column A of sheet "required_refs", upon double clicking a red colored F25 cell, put the value of D25 (of sheet "JE"), and put it in cell D1 on sheet "references".
I've taken a crack at it as best I know how. I've placed this code in sheet JE:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim project As Range: Set project = Range("D7:D446")
Dim param As Range: Set param = Worksheets("references").Range("D1").Value
For Each cell In project
If project.Value = Worksheets("required_refs").Range("A:A").Value Then
Call gotoRef_ 'macro that simply selects/navigates to the required_ref sheet
project.Value = param
End If
End Sub
Thanks so much in advance for any suggestions on how to complete this. I can elaborate on this further if needed.
This will do what you want:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Intersect(Target, Range("F7:F446")) Is Nothing Then Exit Sub
Dim varReference As Variant
varReference = Columns("D").Cells(Target.Row).Value2
If Not IsError(Application.Match(varReference, Worksheets("required_refs").Columns("A"), 0)) Then
Worksheets("references").Range("D1").Value = varReference
End If
End Sub
Important Points:
Whenever working with event handlers, always limit the scope of the target range in the first line. Otherwise, it might not work correctly or it could slow done your spreadsheet.
Make sure your JE sheet column D values and required_refs sheet column A values are all either text or numbers. Otherwise the values won't be compared correctly.
Note the usage of Application.Match() instead of WorksheetFunction.Match() to access the worksheet function. This, coupled with the use of a Variant type variable, allows us to trap the error that occurs if the match fails.
You can always do this on the sheet. Consider the MATCH function. See here for how to use MATCH.
Or another great tool if you're searching for something in a table associated with a value in another column (not your case I don't think)--VLOOKUP formula. Place this formula in the D cell of the sheet you want to place the numbers in. VLOOKUP is in the following format:
=vlookup(lookup value,table_array,column index number, [range lookup])
The lookup value is the 6 digit code you're looking for (on the JE sheet)
The table_array is simply selecting the values you want to search for (required_refs sheet)
The column index number would be one, since the table only has 1 column. It's basically the column number of the value you're looking for.
And range lookup is for if you think there might be more than one place where it matches.
For your case I think it would look like this:
=vlookup('JE'!D1,'required_refs'!A1:A,1,FALSE)
Then just lock the values you want to keep and click and drag down.
Explanation for VLOOKUP here

Sorting Worksheet data by column values using Excel VBA

I have next userform developed in vba, which takes info from a worksheet for displaying info
I want to order all the info aphabetically by a Segment, this is the code:
Function llenarDatosTabla()
Dim vList As Variant
Dim ws As Worksheet: Set ws = Worksheets(BD_PRODXSIST)
ListBox1.Clear
With ws
If (IsEmpty(.Range("AA2").Value) = False) Then
Dim ultimoRenglon As Long: ultimoRenglon = devolverUltimoRenglonDeColumna("A1", BD_PRODXSIST)
vList = ws.Range("AA2:AA" & ultimoRenglon & ":AL2").Value
If IsArray(vList) Then
Me.ListBox1.List = vList
Else
Me.ListBox1.AddItem (vList)
End If
End If
Me.ListBox1.ListIndex = -1
End With
Set vList = Nothing
Set ws = Nothing
End Function
how to make it ordered by 'AD' (SEGMENTO) column???
You can sort your Excel Worksheet in ascending order using VBA statement like the following:
Columns("A:XFD").Sort key1:=Range("AD:AD"), order1:=xlAscending, Header:=xlYes
Note: in the column range Columns("A:XFD") instead of XFD enter the last used column pertinent to your case, e.g. Columns("A:DD").
Hope this will help.
To sort a data table, use Excel Names in conjunction with the CurrentRegion function. This is less risky than hard-coding column references and can be done in two simple steps.
The reason it's preferable to specifying columns is that if you get the columns wrong or they change later, you'll scramble your data! When you perform the sort, the cells in any omitted column(s) will remain where they are, becoming part of the wrong rows. And this is exactly what will happen if you add further columns later, unless you remember to update your VBA.
Here are the two simple steps for using this approach. For this example, I've chosen a data table with four columns and four rows:
We are going to sort by COL3 descending. The cells in the other three columns share identical values, enabling us to readily verify they all stay with the correct rows.
Step 1: choose a cell in the data table that's unlikely to ever be removed, such as the header of a column you intend to make permanent, and define a Name for this cell. You can define the name by selecting the cell and typing directly in Excel's Name dropdown above the worksheet. Here I've used the name RegionTag:
Straight away, CurrentRegion can reference the whole data table just from this. You can see it in action if you code a line of VBA to select the table:
Range("RegionTag").CurrentRegion.Select
This is the result:
That's just for illustration, showing the power of the Name/CurrentRegion combination. We don't need to select the table in order to sort it.
Step 2: define a second Name, this time for the column you want to sort by:
Make sure the Name refers to the entire column, selected by clicking the column header, rather than just a range of cells in the column.
That's it! With these two Names defined, we can sort the data table without concerning ourselves with its rows and columns, even if more are added later:
Range("RegionTag").CurrentRegion.Sort _
key1:=Range("SortCol"), order1:=xlDescending, Header:=xlYes
Here is our data table sorted using the above statement:

Excel: Use values in a sheet as index to list in a different sheet and replace values in the first sheet

I have an XL file with some data to be manipulated. I think I will need to use a VB script to do this - but perhaps there is a simpler way with a formula. Just the same, could someone point out BOTH ways of achieving the following?
I have a column of numeric values (ID) in Sheet 1.
I want to use each ID as an index to lookup a list in Sheet 2.
Sheet 2 has two columns
First column is the index and Second column is the Text String
e.g.
1 Apple
2 Orange
3 Pear
What I want is to replace the column of IDs in sheet 1 with the looked up text string from Sheet 2!
Thats all...
Please help!
Not a tough situation there. Here are some solutions...
With VBA:
I know you said you're a little new with VB so I tried to explain each line as I went along. Also, the code is free-handed so forgive me if I left an error in there somewhere.
Sub replaceData()
dim i as integer, j as integer 'These are just some variables we'll use later.
dim sheetOne as worksheet, sheetTwo as worksheet, myWb as workbook
dim myData as string, myId as string
set myWB = excel.activeworkbook 'These three lines set your workbook/sheet variables.
set sheetOne = myWB.worksheets("Old Data")
set sheetTwo = myWB.worksheets("New Data")
for i = 1 to sheetTwo.usedrange.rows.count 'This loops through the rows on your second sheet.
myId = sheetTwo.cells(i,1).value 'This assigns the value for your id and the data on your second sheet.
myData = sheetTwo.cells(i,2).value
for j = 1 to sheetOne.usedrange.rows.count 'This loops through the rows on your first sheet.
if sheetOne.cells(j,1).value = myId then 'This checks each row for a matching id value.
sheetOne.cells(j,1).value = myData 'This replaces that id with the data we got from the second sheet.
end if
next j
next i
end sub
With an Excel formula:
Place the following formula in cell C1 of the first worksheet (the
sheet with the IDs you will be replacing). **Note that you will
have to replace the "InsertSheetTwoNameHere" portion with the name
of your second sheet (don't remove those single quotes though). Also
note you will need to replace the "1000" with the number of the last
used row in sheet two.
=vlookup(A1,’InsertSheetTwoNameHere’!$A$1:$B$1000,2,FALSE)
Next simply drag the handle on the cell that makes it copy itself
(whatever the heck it's called) all the way down to the end of your
range.
Next, copy those cells and then paste them over the IDs using the
Values Only setting.
Hope this helps and good luck.

VBA - Search and remove duplicates

I'm looking for an algorithm for which I do not have the VBA knowledge to script myself. So I'm stuck. It isn't through lack of effort trying because I have given it a go (plus, this bit of code is the last remaining piece of my bigger VBA code) I simply lack the knowledge/experience/skill...
Basically, I have an Excel file. In this file is a sheet, "sheet1". Sheet1 contains many rows of data. The number of rows contained in sheet1 can vary from 1 to n. Sometimes, I may have 50 while other times I may have 30, etc. What is consistent is the layout of the book, i.e. I have codes in column A which identify a product in my database.
What I want to do is this:
1. Scan the sheet for empty rows (due to the way the workbook is generated, I sometimes have blank rows) and remove them. These blank rows are sometimes in-between rows with data while at other times may be trailing at the end of the sheet.
2. After removing the blank rows find the last used row. Store that to a variable. I have found this piece of code useful for doing that:
mylastrow = myBook.Sheets("Results").Cells.Find(what:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
3. Starting from the row determined in (2), I want to take the product code in A(x where x = mylastrow) and find any other occurrences of it (in column A). If any are found, delete that entire row corresponding to it. Importantly, this loop must go in reverse. For example let's say mylastrow = 40, the loop will need to begin at A40 and on the next iteration do A39 (or 38 if a row has been removed?). This is because with any of the product numbers the corresponding data in the row contains more data further down the column (because of the way the sheet was generated). Essentially the entry closest to the last row is the most recent.
Hopefully I've been able to explain the situ properly. But if not and you're willing to take the challenge (my burden?) off me I would be very grateful.
QF
The only way to develop that knowledge and skill is to get in there and code! I'm sure someone may come in and write you the entire procedure, but in the meantime these resources should give you the tools to do it yourself.
First, check out the method here to delete blank rows. It relies on "Selection" for the range, so you can either manually select all the cells of the sheet, then run the macro, or replace it with the following:
Dim r as range
set r = Sheet1.Cells 'now use r instead of Selection
OR (even better) use your code for finding the last used row and set the range from row 1 to "mylastrow".
Next, beginning from "mylastrow", start adding the values in Column A to a Dictionary object (example here). You can use a row counter to decrement from "mylastrow" to 1. Here's an example of how it would work. The key is assumed to be in the 1st column ("A").
Dim dict As Object
Dim rowCount As Long
Dim strVal As String
Set dict = CreateObject("Scripting.Dictionary")
rowCount = Sheet1.Range("A1").CurrentRegion.Rows.Count
Do While rowCount > 1
strVal = Sheet1.Cells(rowCount, 1).Value2
If dict.exists(strVal) Then
Sheet1.Rows(rowCount).EntireRow.Delete
Else
dict.Add strVal, 0
End If
rowCount = rowCount - 1
Loop
Set dict = Nothing
Before:
After:
Note that the 1st row hasn't been touched since we stopped when rowCount is 1 (assumes there's a header).