Excel VBA - Inserting column of data at point of function input - excel

I am faced with creating a document in excel that requires repetitive instances of the same column of data at multiple points in the sheet, but they arent in 'regular' intervals - so i would like to have a function to both insert new rows and paste the data based on the current active cell (the cell into which i put in the function, or similar). Based on some basic googling it felt like it should be fairly simple with some Range commands, but the farthest ive gotten is #value! instead of compile issues. Guessing it is due to the range functions not quite being set up correctly in my code
Sub insertcopy()
Range(Sheet2!A2, Sheet2!A82).Copy
Range.Insert
End Sub

Related

SUMIF in multiple sheets without using INDIRECT

Here is simplified EXCEL file I am working on.
Data sheet 1 called "first":
Data sheet 2 called "second":
Data structure and range (C2:E8) is same. I need to sum those sheets based on criteria in column B (Option).
Outcome I expect:
option1_sum sheet:
option2_sum sheet:
I can achieve this by putting either this formula in sum sheet C2 and dragging to E8:
=SUMIF(first!$B2,$B$2,first!C2)+SUMIF(second!$B2,$B$2,second!C2)
or this:
=IF(first!$B2=$B$2,first!C2,0)+IF(second!$B$2=$B2,second!C2,0)
These works as expected. Calculations are fast. The problem is that in original file there are ~100 data sheets to sum and area is more than 30000 cells in each sheet.
Formulas are getting very long and file is getting too heavy, takes ages to open.
If there wouldn't be IF condition I would calculate like this:
=sum(first:second!C2)
I expected SUMIF to work like this:
=SUMIF(first:second!$B2,$B$2,first:second!C2)
Unfortunately it doesn't. Every solution I've found uses INDIRECT formula like this:
=SUMPRODUCT(SUMIF(INDIRECT("'"&Sheetlist&"'!B2"),$B$2,INDIRECT("'"&Sheetlist&"'!C2"))) where Sheetlist is named list:
It does work, it is much shorter and makes file lighter more than 3 times, but because INDIRECT is volatile formula, it freezes excel for 5 seconds every time change is made in data sheets. And changes are made often.
Are there any other ways to make file lighter without losing speed?
Limitations:
Can't use VBA because it is stored in Sharepoint and accessed via both Excel 365 and browser Excel
Can't use manual recalculation as it is constantly monitored by several people and changes need to be seen on the spot
UPDATE: #JvdV suggested formula works, but after adding 10+ sheets every recalculations takes more than 5 seconds.
Updated said formula to include blank cells:
=LET(x,WRAPROWS(TOCOL(first:last!A1:E8,0),5),IFERROR(DROP(REDUCE(0,A2:A8,LAMBDA(a,b,VSTACK(a,BYCOL(FILTER(DROP(x,,2),(TAKE(x,,1)=b)*(INDEX(x,,2)=B2),0),LAMBDA(c,SUM(c)))))),1),0))
Using a custom function from the name manager comes to mind. Something like =TOCOL(GET.WORKBOOK(1)) would spill all sheetnames but it requires to save your workbook as .xlsm. So I came up with another idea. If your sheets are always in order you could do something like:
=WRAPROWS(TOCOL(first:last!A:E,1),5)
Now let's incorporate this into a REDUCE() to fill all cells in each sum-sheet:
Formula in C2:
=LET(x,WRAPROWS(TOCOL(first:last!A:E,1),5),IFERROR(DROP(REDUCE(0,A2:A8,LAMBDA(a,b,VSTACK(a,BYCOL(FILTER(DROP(x,,2),(TAKE(x,,1)=b)*(INDEX(x,,2)=B2),0),LAMBDA(c,SUM(c)))))),1),0))
Note that 'last' is just a placeholder for whatever is the last sheet in the sequence of sheets to sum from. I hope that below visual will help cover the basics of the theory implemented:

Showing a complete row using two variables in Excel

I want to ask whether it is possible to have excel print out a complete row of raw data using two variables. So like let say we have the following data:
What we wish to have is that based on the values "2018" and "A", excel should give out the complete row data automatically as done so in the yellow cells.
I know how to do it for one variable, where I have been using
Index(range,MATCH(value, range,0),column())
But I am having difficulty when there are two unique variables, based on which the row data must be extracted.
Currently, I do it in two steps. So I first filter out the year and then use the above formula to extract the row data for A or B. But it is not a very good approach and would appreciate if it can be done using a single formula.
Does anyone has any clue on how it can be done without using Pivot Table?
UPDATE
Regarding the suggestion of using VBA. Using the VBA is a good option, since then I can just use the autofilter command, but the problem is defining the cells in VBA and also how can I have one code for two different columns?
My vba code which I have used for filtering the tables is the following:
Sub Autofilter_Filter12()
Dim lo as ListObject
Dim iCol As Long
Set lo = Sheet3.Listobjects(1)
iCol = lo.ListColumns("Year").Index
with lo.Range
.Autofilter Field:=iCol, Criterial:="XXXX"
End Sub
Now the problem with the VBA code is:
it is only applied for one column and not both.
Instead of XXX, how can I define a cell into the VBA? I have tried but failed again and again.
Thank you for the help.
If range C:H is always numbers then you can use SUMPRODUCT.
=SUMPRODUCT(($A$2:$A$5=$A$7)*($B$2:$B$5=$B$7)*C2:C5)
parameter 1 parameter 2 Value to return
In C7, then select C7:H7 and press CTRL+R.
This results in this:
When this fails it will return 0.
Not very nice, but it could be partially solved with I7 =
=IFERROR(IF(SUM(C7:H7)=0,"Filter failed",""),"")
In EXCEL 365 with dynamic formula you can put multiple columns in MATCH formula by merging them with &
=MATCH(A7&B7,A1:A6&B1:B6,0)
So you can use index-match combination for your case (no matter if values are nubmers or not):
=INDEX(C$1:C$6,MATCH($A$7&$B$7,$A$1:$A$6&$B$1:$B$6,0))

(MS EXCEL) How do I replace cells with formulas to its calculated value AUTOMATICALLY?

I am making a payroll program in Excel and one of my concerns is that the salaries of the employees are searched using the INDEX and MATCH or VLOOKUP function. The problem is if the salaries get updated in the future (e.g. a raise or changes in rates), all the previous entries that used the old salaries will be updated to the new salaries. This is a disaster and would make my entire program useless and inefficient. Therefore I need to automatically lock previous calculated cells after a certain time.
Edit: Note we do not want to do this manually such as copy pasting values only because almost all cells are connected to each other and one mistake by the encoder or if they forget to do this before updating a value, everything will be messed up.
No! Not copying and pasting, there's a simpler way. You want to convert the Formula property of a given cell (what's shown in the formula bar in Excel) into the Value property of the cell (what's shown in the cell on the spreadsheet). For a given range A1:B6 this would done by the statement
Range("A1:B6").formula = Range("A1:B6").value
But there's a quirk in Excel that you can run faster by accessing a Value2 property, so
Range("A1:B6").formula = Range("A1:B6").value2
The rest of the code is left as an exercise for the reader :-)

I have a worksheet that does not populate in certain cells or has errors (ie #DIV/0!), I think it is my function statement

I have a worksheet that does not populate in certain cells or has errors (i.e. #DIV/0!) I have validated the data is there on other ref tabs in the workbook but I believe the functions to be wrong, they work on some cells but not the others surrounding it. I have intermediate skills in excel and the functions being used are unfamiliar to me.
This the function that I am using:
=SUMPRODUCT(($A$2='ShippedQtyPrivate-Input'!$B$2:$B$818)*
('ShippedQtyPrivate-Input'!$A$2:$A$818=BR$2)*
($A16='ShippedQtyPrivate-Input'!$C$1:$H$1)*
('ShippedQtyPrivate-Input'!$C$2:$H$818))
But every 1st - 4th column after a populated column has no data. I don't understand why it doesn't work on all columns.
It depends how you want to handle the error. If you just want the cell to show the text 'Error' then the following should work:
=IFERROR(SUMPRODUCT(OFFSET(BM122,0,$G$1-8,1,8),OFFSET($BM$14,0,$G$1-8,1,8))/SUM(OFFSET($‌​BM$14,0,$G$1-8,1,8)),"Error")

Is there any way to speed up excel comparision in VBScript?

I first made a VBA script to compare two excel files. Then optimized it using Variant as said in this question. But then, I changed it to VBScript later. Here the method said above doesn't seem to work.
Are there any other better ways to speed up the process? Especially for large files.
My core code is as follows:-
For Each cell In objxlWorksheet1.UsedRange
If cell.Value <> objxlWorksheet2.Range(cell.Address).Value Then
'fill the color in the cell if there is a mismatch and Increment the counter
objxlWorksheet2.Range(cell.Address).Interior.ColorIndex = 3
counter=counter+1
End If
Next
It depends on what it is that you are comparing. If you have two sheets with similar tables of data it would be easier to use formulas instead of VBA code. Just create a new worksheet and enter a formula like this: =Sheet1!A1=Sheet2!A1 Then you can use Ctrl-Find to search for False
Or if you can copy the data on one sheet side-by-side, you can use conditional formatting to highlight values that are different.

Resources