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.
Related
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.
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).
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.
I have two workbooks with identical sheets and I need to test whether the data they are getting (from different sources) is identical or within a certain threshold. This, I am already able to do fine. I create a third workbook which calculates the difference between the two.
However, the issue is that one workbook updates seconds before the second which means that if a cell gets two quick updates my calculations would lag behind.
So what I was thinking is that I make a note of the cell value in workbook 1 (the faster updating workbook) and if at anytime up to x seconds after workbook 2 cell has the same value as noted, they are good.
...but how would I go about this, is VBA even the best tool for this?
Any ideas?
using timestamps and vba - or maybe even conditional formatting and some good formulas - could solve this for sure.
However, without anything to work on, it is quite a big step to present you a solution.
Basically you would just create timestamps (internally as variables, or during the import process in cells) and then compare your values, after your threshold ran out. If the values of your compared cells still match, then it's ok.
However, this is all quite dependant on how you solved your dataimput and comparison.
My basic feeling, after I red your question was: "why wouldn't you just decrease your update rate of your calculation?"
Another idea: just use an indicator cell, switching between 1 and 0 or so, to indicate, if an update already happend - so, if you compare, you compare value+indicator. which is basically using timestamps without time.
Well this is not the first time im asking these question here but I cannot make it over.
I have to delete the duplicate rows in a column. say from
range("A1:A30000") have to delete all the duplicate rows in these columns
I have used the previous solutions from my previous questions given by the programmers on the stackoverflow. They are working amazing but not these time.Last time I had each row of 15 columns but these time each row with 40 columns and none of the scripts working. The pc its just getting hang and sometimes taking 2 hrs thats not what i want. I have used the dictionary method as suggested by Issun,Jon,Reafidy and Doc brown even they are not working. I dont know why.
So I thought to use the advanced filters but im unable to delete the duplicate rows from vba. I dont find it on google, I see the manual one with the boxes but not the vba script even i find its not working fine.
Range("A1:A5").AdvancedFilter Action:=xlFilterInPlace, Unique:=True
What I have to do after applying that line. delete the duplicate rows now. I remember its like copy pasting but i dont remember the code well and something like
xltypeinvisble:delete
I dont remember the code well . I remember that i read on google now im unable to find it.
can anyone tell me to delete the duplicate entries using the advanced filter method ? do you think ,that rows had 40 columns each and that made my scripts to take long time and sometimes hang up?what might be the cause to it?
any other method which is faster is appreciated (probably dictionary one). I belive people say dictionary method but i dont know its not working fine may be the code error or not sure about the reason.its just getting hang up. so unable to know why, well its working fine for small data that i tested. but not with the bigger one.
any help is greatly appreciated!
I'm not familiar with the single line command you are looking for to delete all invisible rows at once, but you can loop through the rows in the range and manually delete them.
If this still runs too slow for you, you may want to consider adding the VBA commands to turn off screen updating and re-calculations while the macro is running.
Sub DeleteDUpes()
Dim ThisRange As Range
Dim NewRange As Range
Set ThisRange = Range("A1:A30000")
ThisRange.AdvancedFilter Action:=xlFilterInPlace, Unique:=True
' Loop through each row from bottom up, deleting rows hidden by filter
For thisrow = ThisRange.Rows.Count To 1 Step -1
Set NewRange = ThisRange.Resize(1).Offset(thisrow - 1, 0)
If NewRange.EntireRow.Hidden Then
r.EntireRow.Delete
End If
Next
End Sub