Conditional statement to delete rows based on values in two columns - vba

I've tried searching here and generally through Google to find a solution to suit my needs, but have come up empty. I'm new to using Excel VBA, but I assume this is the correct way to go about things in this case.
I have a large spreadsheet - many worksheets with thousands of rows in each. Each worksheet has similar data in it. There are 5 columns, A-E. Column C has duplicate data, and column E disambiguates it. What I'm looking for is a way to delete rows when the condition of "If c28=c29=c30=c31, and e28:e31 contains '.tif', then delete rows where e28:e31 is not '.tif'."
I hope this makes sense.
Thanks for any help!

I do not understand why people waste so much time searching for exactly the code they need for a problem that is unique to them. It would be so much easier to learn the basics of VBA and then code their solution themselves
Search for “Excel VBA Tutorial”. There are many to choose from so pick one that matches your learning style. I prefer books. I visited a good library; borrowed the most promising Excel VBA Primers to study at home then bought the one I preferred as a permanent reference book. A few hours learning VBA and you could solve this problem and the next and the next without wasting hours wandering around the web looking at code you do not understand.
Think about your requirement. I assume c28=c29=c30=c31 is an example. c31=c32=c33=c34 would also be of interest. You need to generalise your specification.
I will replace c28 by Cells(28, "C") which happens to be VBA syntax but any suitable notation will do at this stage. I think you mean:
Cells(RowCurrent, "C") = Cells(RowCurrent+1, "C") And _
Cells(RowCurrent, "C") = Cells(RowCurrent+2, "C") And _
Cells(RowCurrent, "C") = Cells(RowCurrent+3, "C")
for all permitted values for RowCurrent.
What are the permitted values for RowCurrent? If you have one header row, the first data row will be 2 so the minimum value for RowCurrent will be 2. If RowLast is the last used row of the worksheet, the maximum value for RowCurrent is RowLast – 3.
When you say e28:e31 do you means cells e28, c29, c30 and e31 have been merged?
Do you mean e28:e31contains .tif or e28:e31ends .tif? Would you keep abc.tif.txt? When programming, your specification must be absolutely precise. The computer will do what you say not what you meant.
You say you have many worksheets and you want to read each of them in turn. I would expect any tutorial to explain how to loop through all the worksheets of a workbook. Alternatively, this is the sort of question you can search for. If you have a single requirement, you can usually find a suitable match. Put another way, searching for D may be easy but searching for A and D and I is difficult.
You have an outer loop for each worksheet. You need to find the last used row of each worksheet. You have an inner loop for each block of rows. You need to delete uninteresting blocks. I would expect you to learn how to do each of those from your tutorial. Can you put those four separate techniques together?
I can only see one serious complication with your requirement; you do not delete uninteresting rows, you keep interesting rows. If you examine rows 2 to 5 and find they do not conform to your template, you cannot delete them because rows 3 to 6 might conform to your template. I do not believe you could possibly find any code that would meet this requirement. You would have to design the solution yourself. I have a couple of suggestions but I would need to have more confidence in your exact requirement before suggesting them.

Related

Macro to update column data with vlookup result

I have two spread sheets, Sheet1 & Sheet2.
Sheet2 will be a paste of a lot of information received from a third party with a unique ID in column B, I’m currently using vlookup but the spread sheet is getting very large and taking a long time to load up and save.
In sheet 1 I'd like to use a macro to insert the vlookup result from a MACRO matching the unique ID in column B and displaying the value of column c from Sheet2.
Hope this makes sense, thank you!!
Tried a lot:
Sub UPDATE()
Dim s1 As Worksheet, s2 As Worksheet
Set s1 = Sheets("Sheet1")
Set s2 = Sheets("Sheet2")
v1 = s1.Range("A2")
v2 = s1.Range("B2")
s2.Activate
For Each r In Intersect(ActiveSheet.UsedRange, Range("B:B"))
If r.Value = v1 Then
r.Offset(0, 1).Value = v2
End If
Next
End Sub
If you can post a non-question in the question field, then can I post a non-answer in the answer field?
The help you need right now is not the help you kinda, sorta, but not really asked for. You just don't know it yet.
If I stop judging your intent between the lines and ignore your insulting response to a genuinely helpful comment. If I take the time and energy to focus on your problem and semantically transform your demand into a question. Then you still will not get what you asked for.
I shall demonstrate.
A large workbook with 2 sheets loads and saves slowly. Presumably because of its size and numerous vloookup functions. To improve performance you want a macro on sheet 1 to “insert the vlookup result from a MACRO” on sheet 2.
This may surprise you. If a formula is already optimized then replacing it with another formula will not improve performance. Even if that formula is a vlookup and even if that vlookup is placed by a MACRO. In fact, it will be slower because you're still calculating the vloookups and now you've added the overhead of running the macro on sheet 1 and the MACRO on sheet 2. Seems to me like you might get a performance boost by changing your calculation settings to calculate before save and do not refresh or calculate when opening. That won't improve your save time but opening and working with document should be faster.
That's an answer you didn't ask for but it's weak and really doesn't do much to get to the root. I'm really trying to help so I won't stop yet I'll dig through the code you shared and focus on the pieces where you think the problems are. Oh, you didn't say where they could be. No big deal, it's a short block and I'm almost VBA literate, I'm sure I won't have any issues fixing bugged code as I step through it in my head without access to test data or your runtime environment. Piece of cake!
Umm… what are you trying to do? I think I understand what you said you want; but I don't see how you actually went about doing it. I'll work with what you gave me but it isn't much so I hope you don't have high expectations.
Sheet 1 and 2 are set. 2 is activated and this sub starts working with it; therefore, this must be the sheet 2 MACRO. How does this interact with the sheet 1 macro? Are you certain there's no problem with that one?
Hrmmmm, I've read a little about the speed of intersection. If i recall correctly, it's supposed to be quite fast, that might be a good choice. I'll have to remember that. Uh, B:B, the whole column? You can often gain performance by narrowing constraints, but I am not certain in this case. Maybe intersection is a of short circuiting every row that follows, i should look into that.
I have to assume v1 and v2 are variants because they aren't declared and no information is given regarding option explicit or publicly scoped variables. You have to be careful variants because they can change type and cause you to throw errors all day. Especially if your code isn't clear enough to identify them on sight. Case and point, you assign 2 variants equal to a range, is this intentional or did you forget the word set? Further down you assign the value of a range to the same variant leaving me to guess about your intent.
Does your data use strings? If it does then value2 should be faster than value.
I'm confused about your loop I don't know why you have it or why you're do what you do. You said you have vlookup results pasted in B - so it makes sense that you read it. But why in a loop? You calculated a valid range, why not write if to an array in one step instead of potentially hundreds or thousands? Why are you writing to column C in sheet 2? I would have expected sheet1.
Wait, that's it? That's all your code does? They're must be something else because there is no way for me to get from where you are to where you said you want to be without acting like your personal code writing service.
So there it is. In detail. A genuine attempt to give you what you asked for. How much closer to your goal are you now that I've spent more than 2 hours offering my hand?
Probably not much.
Unsurprisingly the most helpful piece of information, the one that will get you the closest to your goal, was given to you in the first comment and it reflects poorly on you to respond in the manner you did.
From my perspective, it looks like you haven't figured out what you need to know. I'd start with with option explicit. Then transferring data between sheets. Then using ranges with arrays. That should get you to a point where we can actually help you. That's 3 topics and 1 of them is a 20 second read.
Good luck, and try to lose the attitude.

Compare sheet1 columns(400) data matching with sheet2 columns(500) as different column order

sheet 1 have 400 columns and data row upto 10000 rows, i want to compare with sheet 2 it has 600 columns means with additional columns in different order.
Compare sheet1 columns data with sheet2( as different column order) and highlight difference in sheet 2 and put difference in sheet 3 with highlighting the cell for mismatch, im new to VBA need your support,
you can highlight any one column as a primary column in sheet 1
Instead of hoping someone will write your code or teach you from scratch, you might have better luck with putting some research into how to do this with Excel's built-in tools. Therefore, my answer is "don't use VBA" — organizing data is what Excel is meant for and there is plenty of built-in functionality that you're probably not aware of.
First, there's Spreadsheet Compare (available in certain versions), which compares two workbooks (or two versions of the same workbook) and helps you see and organize differences between them. You can also identify potential issues, such as changes in formulas or calculations, or manually entered values.
Also built-in, see Consolidate data in multiple worksheets, allowing you to summarize and report results from separate worksheets into a single document. The sheets can be in the same workbook, or in other workbooks. When you consolidate data, you assemble data so that you can more easily update and aggregate as necessary.
If the columns are in different orders between the worksheets and that causes an issue for you (or for the built-in tools) is a problem, a simple fix is to simply sort the columns alphabetically on both sheets. In order to do this you just need to choose Left-to-Right in the Sort Options.
I'm sure there are other relevant features I'm not thinking of; take a look though "all" the commands available on your version's ribbon to see if there are other commands you're not aware of.
There are also a number of worksheet functions that could also help with a process like this. Exactly which ones depends on your needs (impossible for others to advise on without knowing the details of your current organization method).
The Insert Function Dialog
Off the top of my head, VLOOKUP, HLOOKUP, INDEX, MATCH, FIND, MID, LEFT and RIGHT could all potentially be beneficial to this task. (And still, no VBA required.) Find out more on those at the official Categorized List of Excel Functions, and also see the Lookup Functions section specifically.
Finally, there are a number of free or paid third-party add-ins specifically for Comparing & consolidating worksheets. For example, here is a lengthy list of the comparison functionality offered by DiffEngineX.
It's very common for Excel users to have a task at hand and assume that it's necessary to dive into VBA, without realizing Excel already provides the functionality they need. As a rule of thumb, ask yourself "Is this unique, or is this something that someone might have needed to do before?" If its not unique, chances are it's either already built-in, or there's an existing solution somewhere online.

VBA : re-sort/re-order rows based on column values through specific range

I'm fairly new to VBA, and have found this to be a great resource. I understand enough to generally find someone else's code and modify it to what I need it to do, but I've been stumped here. I've tried coding this several times in different ways, but can't seem to get it to work, and am not overly convinced I'm approaching it the right way to start with. I'm hoping someone is willing to help me.
Here's a theoretical example of what I'm trying to do.
I have a sheet that contains groups of orders of a certain product type with their quantities listed by the step of the process they're currently at:
Current orders in process
I need to "sort" them or re-order them so that:
1. The orders are copied into a tab based on process step, with the furthest process step being listed first working back to the closest, and...
2. Orders listed in the "complete" step need to be excluded completely, and...
3. I need to do this for multiple product types, which have different numbers of process steps, so the end column needs to be identified somehow (as a dynamic variable, or some trigger)
For the example, it would look like this:
Sorted data
I've thought through a half-dozen ways to logically go about this and tried to figure out how to then do that with code, but I'm stuck ... and I have the feeling that there is probably 1 or 2 "best" ways to go about this that someone in this community probably knows off the top of their head. Thank you in advance.
Edit: Here's my first attempt at coding the outline. I realize there are some components missing, but would love feedback on whether this seems to be a usable, or efficient approach.
Sub test1()
Dim skuStartRow As Long, skuEndRow As Long
Dim qty As Integer
Dim colCheck as long, lastCol as Long
skuStartRow = .Range("A:A").Find(what:=sku, after:=.Range("A1")).Row
skuEndRow = .Range("A:A").Find(what:=sku, after:=.Range("A1"), searchdirection:=xlPrevious).Row
' Code here to identify last column (lastCol) either by .UsedRange or by header?
For colCheck = 3 To lastCol
For rowCheck = skuStartRow To skuEndRow
qty = Cells(rowCheck, colCheck).Value
If qty <> "" Then
'copy current row and paste into destination worksheet
MsgBox qty 'test to see if correct qty is displayed
End If
Next rowCheck
Next colCheck
End Sub
Update:
Still having problems.
I've copied/pasted the whole range of orders based on product type to a new sheet where it will be sorted.
I've inserted a column and used the match/index formula provided by Variatus (autofill down) to create an index column.
Insert new column and use RANK function to create a rank ordered list, as there are duplicates in the Helper/Index column.
Used INDEX/MATCH functions to return values into rank ordered lists for both work order number and quantity value.
The code I currently have works - except that it's hard-coded using FormulaRICI = ... commands. I'm having major challenges figuring out how to convert the code to allow use of MATCH/INDEX functions with variables. I need to do this b/c depending on product type there are varying amounts of total orders, as well as varying amounts of number of steps; so I need to have a dynamic range for both rows/columns.
I've looked at a bunch of examples but can't seem to find something that works correctly. The most promising I've seen appears to be using the "replace" function in VBA, but my head's about to explode.
Any suggestions are much appreciated.
I wonder if you really need VBA for this. Please consider these steps.
Insert a column in your worksheet with this formula in row 2, copied down.
=IFERROR(MATCH(TRUE,INDEX($D2:$I2<>0,0),0),0). The range D2:I2 is defined by D2 = Step 1 and I2 = "Complete". The formula finds the first non-blank cell in the range. The column could be hidden.
Sort the sheet on the helper column, largest to smallest.
Apply a filter.
Filter on the product.
What you see at this point is the list you wish to create using VBA, however including the 'Complete' column and any other columns to the right of it.
There are a number of ways of automating this process. You might write code to either insert the formula in the helper column automatically or its result. This could be done when needed, without having a permanent extra column. You could write code to do the sorting and filtering automatically, for example, based on a currently selected product. And, finally, you might write code to copy the result to another sheet, remove the unwanted columns there, and restore the original sheet to its original condition (presumably sorted by order number).

VBA Delete blank rows in a given range on Excel [duplicate]

This question already has an answer here:
Excel VBA: Delete entire row if cell in column A is blank (Long Dataset)
(1 answer)
Closed 5 years ago.
Before thinking to flag this as a duplicate question, please let me assure you that I found not an answer satisfying this very simple need.
So I have a picture included to help me describe what EXACTLY I want to do.
Please scroll down and pass the picture.
Imagine data being set in a neat way.
Rows 1 to 9 must stay untouched.
Rows 22 and so on must stay untouched.
From line 21 to 10 (that way intended) I want the code to check if the line is blank.
If the line is blank I want the line deleted. Removed entirely.
Otherwise, I want it untouched.
Thus in the picture, lines 1 to 9 stay untouched.
From lines 21 to 10, only 10 and 11 stay.
Lines 22 and so on stay untouched.
Checking the first cell if it is null, will do the trick, I just want the correct syntax to make it happen right and only within A21 to A10 for the example.
It is probably stupidly easy, but for some reason it gives me a hard time to do it right, since I am new to the VBA methods.
I am sure there will be the EntireRow.Delete method involved somehow
I am just not so good yet with what you can do with VBA yet.
The first answer to this question was pretty near my needs and yet so far.
Excel VBA to delete blank rows within a range
Problem is that I am not very experienced and I don't understand all the methods, neither all arguments passed to that example. It is kinda complex and what I would love to see is something simple, documented in a way to understand what is going on, so I can implement it on my real life scenario.
This question:
Excel VBA: Delete entire row if cell in column A is blank (Long Dataset)
The question has an answer for the ENTIRE spreadsheet, not helpful really in my case.
As you can see, I provide an example, I am not asking you to do my job, I just honestly wanna learn how to do what I asked.
I am not sure if I need a FOR that iterates with negative step -1, including some methods inside the loop, or if there is a ready method for this, including a looping, so here I am asking more experienced people how to do something, probably ridiculously easy.
Any help would be appreciated.
You need to loop backwards from the end of the range and delete the relevant row index, like so
for x=numrows to 1 step -1
if ws.range("a" & x).value="" then ws.rows(x).delete
next x
Where ws is the worksheet you are working on.

Excel auto-fill any row with formula and prevent it from being deleted - programming only way?

Having an Excel problem, I searched the net. Found old answer on stack overflow, but it was both incomplete and also off topic of this forum.
Since incomplete I need a much better solution and fear it will require some (VBA-) programming. Thus I hope it is on topic.
My problem is this:
I have two sheets, one for input of data, and one for presenting/printing them. Because data is never "consistent", I had to make a trick and have a cell in each data-input-row be filled with consistent data for me to do vlookup sucessfull in the printing/presenting sheet.
And yes, autofilling the whole column (row 1 to 653..) initally does the trick.
But when users 1) delete old entries, at best they mark the rows and right click to delete not only data but the entire row, meaning that the number of rows with the actual formula decreases, or at worst just delete data in the row leaving a row without formulas in the cols I need to have rows in.
2) add new entries, they either insert a new row (thus not containing the formulas), by accident delete the formula(s) in the cells (haven't figured out yet how they manage, since the cols with formulas is hidden)
So, is there any way I can ensure that whatever the user does, there will always be formulas in any row in my hidden cols?
Respectfully I am not at all into VB/VBA, so if that is a solution (programming the col to contain the formula no matter what), please bear with me and provide the rookie-understandable answer for me to implement.
Thank you very much in advance!!!
Best regards,
Steen
Additional info:
Sorry if I'm being a real newbie, but if only I could upload a picture or an example file.
My sheet have headings: A is volunteer#, B is date, C is task (gardening, car wash, babysitting, baking, ....), D is hours worked on task, E is points per hour (using Vlookup to find points per hour for each task), and finally F (my problem) containing a formula (points per hour * hours worked).
Since everyone can (and should be able to) input a record ("I am volunteer no 1, and on the 12. of february I did gardening for 3 hours". The formula in F should result in 3 hours * 15 points).
My real formula is a bit more complicated than the example, but .... A formula is a formula.
So, when people fill in new entries or delete previous week-entries etc, it is quite random if they do it in a way that wil have the function in col F work.
If they insert a new row, me having filled entire col F with the function won't work, so they should go to next blank row (perhaps way down) to insert data.
If they delete marking the rows and right click+delete, they minimize number of rows with formula in it. If they mark rows and click delete, we get blank rows without data, formulas, whatever.
So how do I ensure that each cell in col F always will contain my formula no matter what?
Saw someone pointing to something called arrayformula, but couldn't see how I could implement it to work for me (poor examples, sadly).