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

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).

Related

Retaining blank rows while comparing data in Excel

I seem to be in a stump right now and any help would be appreciated.
I have a spread sheet with a bunch of data. Basically, one column of data has multiple names. Each name is associated with an act #. Account Allan may appear 4 times because there are 4 accounts for him.
I need to pull that ONE Allan out and his account #'s into a new column and have the account numbers read across in the row. The file has all account #'s in one column. Which is an issue.
I've managed to complete the first task. Currently what happens is I'll drag down the cell where my formula is and it will in fact only generate ONE copy of the persons name and in the next cell over I have the account numbers splitting as they should in a row now. My only issue is that even thought its pulling just ONE person it's not inserting a blank row where the duplicates would be.
I apparently can't add images considering this is my first post or something so here are the 2 formulas I've used for this so far:
=INDEX($B$2:$B$50, MATCH(0, COUNTIF($L$1:$L1, $B$2:$B$50), 0))
=IFERROR(INDEX($C$2:$C$50, MATCH(0, COUNTIF($L2:L2,$C$2:$C$50)+IF($B$2:$B$50<>$L2, 1, 0), 0)), 0)
The first formula is the one that pulls just one of the persons name if it finds a duplicate and the other formula is the one where it pulls the multiple account numbers if any for that person into a row.
https://i.stack.imgur.com/vwSwZ.png
https://i.stack.imgur.com/gJmnF.png
Based on https://exceljet.net/formula/get-nth-match-with-index-match and matching your columns:
=IFERROR(INDEX($C$2:$C$50,SMALL(IF($B$2:$B$50=$D2,ROW($B$2:$B$50)-ROW(INDEX($B$2:$B$50,1,1))+1),M$1)),0)
Enter it in the first cell with Ctrl+Shift+Enter and then copy the cell over all other cells. This is based on that the column-header has the value 1,2,3,4,5 etc for which nth of the accountnumber. You could refine it to match your headers.
I know this is late for the reply but thank you so much for everyones input especially yours KeshShan! I did end up getting everything to work.
I did use the index match and a couple "IF" statements, see below. Thank you!!
=IF($D2<>"",INDEX($B$2:$B$50, MATCH(0, COUNTIF($L$1:$L1, $B$2:$B$50), 0)),"")
=IF((IFERROR(INDEX($C$2:$C$50, MATCH(0, COUNTIF($L2:L2,$C$2:$C$50)+IF($B$2:$B$50<>$L2, 1, 0), 0)), 0))=0,"",(IFERROR(INDEX($C$2:$C$50, MATCH(0, COUNTIF($L2:L2,$C$2:$C$50)+IF($B$2:$B$50<>$L2, 1, 0), 0)), 0)))
=IF(B2="","",IF(COUNTIF($B2:B34026,B2)=1,B2,""))
Funny thing is, the new issue this project has presented is that it takes absolutely way too long to actually process all of these formulas for over 30 thousand records.
I need to learn more about SQL I heard? I'm hoping to become a Data Analyst one day, get back into school soon to learn more about data (I never thought those words would ever come out of my mouth haha) I actually find it fun and interesting now! I'm currently self taught so I apologize for so many weird questions! Any direct messages about SQL and where I should start would be awesome! Thank you!
Here are the results of these formulas. By looking at these 3 pictures it should be clear to see what I was trying to accomplish. Just needed to split the data in coloumn B & C into seperate rows for a data merge onto a letter.
One
Two
(See next comment for third picture)

Dynamic vertical to horizontal list in excel (using Index, aggregate, etc)

Ok, hopefully my question makes sense as I've been having bad rep of late. I've searched for the answer for a while now but can't find anything so I think I'm safe to ask the question haha.
I'm trying to dynamically list a bunch of rows from one table, to columns horizontally in another table. I think my issue might be a circular reference but I really can't work it out.
=INDEX(mindbld[ID], AGGREGATE(15, 6, (ROW(mindbld[Type Auto])-ROW(mindbld[#Headers]))/(LEFT(mindbld[Type Auto], LEN($A$2))=$A$2), ROW(1:1)))
This is the formula I'm using in my OCCOUT table. This dynamically lists a bunch of IDs vertically in column B from MINDBLD table. Cell A2 contains my criteria for this list: e.g. Office (ids). This works perfectly and is a pretty sweet formula.
=INDEX(tblOCC[[Ten Sched]:[Ten Sched]], AGGREGATE(15, 6, (ROW(tblOCC[[Tenant ID]:[Tenant ID]])-ROW(tblOCC[#Headers]))/(LEFT(tblOCC[[Building ID]:[Building ID]], LEN(occout[#[ID2]:[ID2]]))=occout[#[ID2]:[ID2]]), COLUMN(E:E)))
With this formula I'm trying to list the rows from TBLOCC horizontally. The table has a numerous rows that have information, with the same IDs as found in MINDBLD.
Ten Sched column in TBLOCC has the information I'm retrieving. Tenant ID is the furthest to the left column in TBLOCC. Building ID contains the same ID as found in minbld[ID].
OCCOUT ID2 contains the IDs found by Formula 1 albeit in Column C (e.g. cell C2 =B2) as I thought this might be an issue.
The formula returns a #NUM! and I can't seem to fix it. Hopefully I've made myself clear. I have the feeling this would be much easier with VBA! (Which I don't know).
EDIT #1
Something interesting I've found, formula is in cell E2:
=INDEX(tblOCC[[Ten Sched]:[Ten Sched]], AGGREGATE(15, 6, (ROW(tblOCC[[Tenant ID]:[Tenant ID]])-ROW(tblOCC[#Headers]))/(LEFT(tblOCC[[B ID2]:[B ID2]], LEN($C1))=$C1), COLUMN(E:E)))
This works (referencing an ID above).
However if it references C2 in the same row as the formula it returns an error.

How to randomly distribute a known group of numbers into a column using Excel / VBA

I'm stuck with excel/vba:
I've got a 10 row x 30 column blank array in Excel. I am trying to distribute 10 integers from a known group of 10 (say 1,1,1,1,1,1,3,5,7,9) into each column randomly so that each row of the column contains one of the group (and all of the group members are used once), and I need the second column to contain another random distribution of the same group and so on.
So I'd end up with 30 columns of 10 rows each, with each column containing a different random distribution of the same 10 integers. I want to be able to change the distribution in each row by recalculating the spreadsheet too.
Is there a quick way to do this? Short of arranging 30 different rand() sorted lists and using lookups I couldn't see a way. I'm not savvy enough with VBA to have a go. If someone can point me in the right direction, I'd be eternally grateful!
Perhaps I'm missing something obvious, though this does not seem to be so straightforward using worksheet formulas alone.
If your orginal list of values is in A1:A10, then, in B1:
=INDEX($A$1:$A$10,RANDBETWEEN(1,10))
and in B2, array formula**:
=INDEX($A$1:$A$10,INDEX(MODE.MULT(IF(COUNTIF($A$1:$A$10,$A$1:$A$10)-COUNTIF(B$1:B1,$A$1:$A$10),{1,1}*ROW($A$1:$A$10))),RANDBETWEEN(1,10-ROWS($1:1))))
Copy the above down to B10.
You can then copy the formulas in B1:B10 to the right as desired.
Regards
**Array formulas are not entered in the same way as 'standard' formulas. Instead of pressing just ENTER, you first hold down CTRL and SHIFT, and only then press ENTER. If you've done it correctly, you'll notice Excel puts curly brackets {} around the formula (though do not attempt to manually insert these yourself).
You could make a loop in which you make an array with your 10 numbers. Then loop though 30 columns, with first adding another column of 10 randomly drawn numbers to your array. See this website on how to draw random numbers. Then sort the array on the second column and post the first column.
Edit:
As I read in the comments on the other answer, the purist solution would be to:
Assign each unique option of values a random value
Sort these random values either from top to bottom or bottom to top, and select the top one.
Place it in the first row
Do the same thing again for the second row, but keep track of the sum of all the unique options, as to rule out an option once it maxed its presence.
Edit2:
Once I just clicked post I thought this a bit more through and came to the conclusion that the last digit will allmost always be 1 in this case....

Deleting data in last cell of data in Column A

I am in need of assistance agian. When my macro works, the number 1 is populated in the final cell in column A because the coding is set up to place a number 1 or 2 depending on other data until the last row of data. Since the last row of data has necessary information in other columns, I wanted to delete the 1 in column A because it is not needed. How do I code to take away the value in the final cell of a column? I've tried referencing to it and if statements. I am sure I am missing something simple.
This is my first macro using VBA.
Thanks.
I just started working with VBA in the last day or two, but I believe the thing you are looking for is: Cells(x,y).End(xldown).ClearContents
Alternatively, I think Range("A1").End(xldown).ClearContents would be equally effective.
But I just started doing this myself, so take with spoonful of salt.

Excel - How do I find all relevant rows by typing unique invoice# listed Col A

I have a Worksheet with 10 columns and data range from A1:J55. Col A has the invoice # and rest of the columns have other demographic data. Goal is to type the invoice number on a cell and display all the rows matching the invoice number from col A.
Besides auto filter function, the only thing comes to my mind is VBA. Please advice what is the best way to get the data. Thanks for your help in advance.
Alright, I'm pretty proud of this one. Again avoiding VBA, this one uses the volatile formula OFFSET to keep moving its VLOOKUP search down the table until it's found all matches. Just make sure you paste enough rows of the formula that if there are many matches, there's room for all of them to appear. If you put a border around your match area then it would be clear if you ever ran out of room and needed to copy down the formula some more.
Again, in the main section, it's just a single formula (using index):
=IFERROR(INDEX($A$1:$J$200,$M3,MATCH(N$2,$A$1:$J$1,0)),"")
This gets to be so simple because the hard work of the lookup is done by an initial column which looks up the next row that matches the invoice number. It has the formula:
=IFERROR(MATCH($L$2,OFFSET($A$1:$A$200,M2,0),0)+M2," ")
Here is the working example that goes with those formulas:
Let me know if you need any further description of how it works, but it mostly uses the same rules as above so that it's robust in copying and moving around.
I've uploaded the Excel file so you can play with it, but everything you need to reproduce this feature should be in this solution.
Google Docs - Click link and hit Ctrl+S to download and open in Excel.
A popular solution to this problem is a simple VLookup. Lookup the invoice the user types in on the table A1:J55, and then return an adjascent column's data.
Here's an example of it working:
The formula in the highlighted cell is:
=VLOOKUP($L3,$A:$J,MATCH(N$2,$1:$1,0),FALSE)
What's nice about this formula is you only need to type it once and then you can copy it across and it'll automatically pick out the correct column of the table (that's the match part). The rest is very simple:
The first part says lookup value $L3 (the invoice number typed in),
The second part says look it up in range $A:$J (which is where your table is located). I've shown how you can select the entire columns $A:$J so that you can add and remove data without worrying about adjustin the range in your lookups. (Excel takes care of optimizing the formula so that unused cells aren't checked)
The third part picks the column from which the resulting data will be drawn once a matching row is found.
The FALSE part is an indication that the invoice number must match exactly (no approximate matching allowed)
The $ signs ensure that fixed ranges like the location of your source table ($A:$J) and your lookup value ($L3) don't get automatically changed as you copy the formula across for multiple columns.
The formula is pretty easy to adapt if you want to move around your table and the area where you do your lookup. Here's an example:
Bonus
If you want to add a little spiff, you can add a dropdown to the Invoice # field so that the user gets auto-completion and the option to browse existing values like so: