Excel VBA autofilter crit - excel

I'm trying to set up a filter in excel where the resulting data should include both criteria which are contradicting.
Example:
Set 1
Field =2 ,Criteria1 =x field = 3 criteria= 1
Set 2
Field =2 ,Criteria1 <>x field = 3 criteria= 2
Where the end result is all rows which satisfy either set of conditions
Any help would be appreciated.
Thanks

Related

How to identify different records from two columns in Excel

I have some simple records below in Excel spreadsheet. I did a True/False value in check column (very simple check) for small set of records.
ID table 1 ID table 2 check
180065220 180065220 TRUE
180296833 180296833 TRUE
181457872 181457874 FALSE
181917974 181917974 TRUE
180296568 180593133 FALSE
181279364 FALSE
Here, I re-ordered the ID columns from table 1 and table 2 to identify the different records from these two tables and moved the differences to the bottom. Again, it's in Excel spreadsheet.
ID table 1 ID table 2 check
180065220 180065220 TRUE
180296833 180296833 TRUE
181917974 181917974 TRUE
181457872 181457874 FALSE
180296568 180593133 FALSE
181279364 FALSE
Is there a method/function that can allow me to identify the differences from records from table 1 and table 2 and place them at the bottom? It would not be feasible to manually using my current method for a large tables.
Hopefully this will help - you can use the following formula in column C:
=COUNTIF(B2,$A$2:$A$50000)
It literally takes a few seconds to get calculated for the whole dataset of 50k rows. Then you need to sort your dataset by column C - Sort Largest to Smallest:
It will keep the "common" IDs 1 at the top and push the differences 0 to the bottom. Let me know if it works for you.

Assign values in large scale into a data base. Formula (libreOffice calc)

I am trying to create a data base in libreOffice spreed-sheet application. And what I need is, the first column to be Id's, but each Id has to fill 100 cells. So I would like to have 2000 Id's and each Id takes up 100 cells, we have 200 000 cells. (Id's values = range(1,2000))
row#1 : row#100 = Id#1 // row#101 : row#200 = Id#2 ....// row#199900 : row#200000 = Id#2000
What I simply want is to assign the value 1 to the first 100 cells in the first column, the value 2 to the next 100 cells in the same column and so on, until I have the 2000 Id's in the first column.
So I would like to find a formula to achieve that with out having to select and scroll manually 2000 times the sheet.
Thanks
If the ID is in A column:
=QUOTIENT(ROW(A1);100)+1
The formula adds 1 to integer part of the number of row divided by 100.
Apply with a loop?
Public Sub test()
Dim i As Long
For i = 1 To 2000
Range("A1:A100").Offset((i - 1) * 100, 0) = i
Next
End Sub

Create new Excel rows based on column Heading and populate the data

I have to create output XLS file based on input xls file header. I am giving below exact requirement. hope its clear. if not then please let me know.
Iput XLS -->
ID Version NameLegacy ProjectNumber OwnerName Language Keywords OwnerSite External Content Relevance Periodic Coremap ValidTo
1 1 Mohan 1000 x ENG ABCD AB No ok no 5 2017-10-14 2018-10-14
2 2 Shayam 1001 y ENG EFGH BC No ok yes 2 2017-10-14 2018-10-14
3 1 Sourabh 1002 z ENG IJKL CD Yes no no 4 2017-10-14 2018-10-14
Based on this Input XLS File, i need Output XLS File as below. Each row of input file will have 12 row of output file and respective value will be filled in Output file from input file.
ID Version IBANAME STRINGVALUE INTEGERVALUE FLOATVALUE FLOATVALUEWITHUNITS BOOLVALUE TIMEVALUE URLVALUE REFERENCEVALUE
1 1 NameLegacy Mohan
1 1 ProjectNumber 1000
1 1 OwnerName x
1 1 Language ENG
1 1 Keywords ABCD
1 1 OwnerSite AB
1 1 External No
1 1 Content ok
1 1 Relevance no
1 1 Periodic 5
1 1 Coremap 2017-10-14
1 1 ValidTo 2018-10-14
2 2 NameLegacy Shayam
2 2 ProjectNumber 1001
2 2 OwnerName y
2 2 Language ENG
2 2 Keywords EFGH
2 2 OwnerSite BC
2 2 External No
2 2 Content ok
2 2 Relevance yes
2 2 Periodic 2
2 2 Coremap 2017-10-14
2 2 ValidTo 2018-10-14
3 1 NameLegacy Sourabh
3 1 ProjectNumber 1002
3 1 OwnerName z
3 1 Language ENG
3 1 Keywords IJKL
3 1 OwnerSite CD
3 1 External Yes
3 1 Content no
3 1 Relevance no
3 1 Periodic 4
3 1 Coremap 2017-10-14
3 1 ValidTo 2018-10-14
Thanks in advance.
There are a few steps to do this using VBA. The main purpose is to identify what you are actually trying to do.
It seems like you are attempting to sort through records to identify what the format of the information is and place it in a column designated for only that format. To do this, I have created a very simple custom Function..
This function takes in the name of the header as a string, and uses Select/Case to find appropriate matches for which column the target sheet needs. This is custom to your specific layout. Feel free to adapt or change it.
FUNCTION TO FIND CORRECT COLUMN ON TARGET
Function ColFinder(header As String) As Long
'Target Column Format = Column #
'"STRINGVALUE" = 4
'"INTEGERVALUE" = 5
'"FLOATVALUE" = 6
'"FLOATVALUEWITHUNITS"= 7
'"BOOLVALUE" = 8
'"TIMEVALUE" = 9
'"URLVALUE" = 10
'"REFERENCEVALUE" = 11
' **** SET VALUES FOR CASES TO MATCH DESIRED FORMAT ABOVE ****
'Default to Column 4 StringValue if unknown
Select Case header
Case "NameLegacy"
ColFinder = 4
Case "ProjectNumber"
ColFinder = 5
Case "OwnerName"
ColFinder = 4
Case "Language"
ColFinder = 4
Case "Keywords"
ColFinder = 4
Case "OwnerSite"
ColFinder = 10
Case "External"
ColFinder = 8
Case "Content"
ColFinder = 11
Case "Relevance"
ColFinder = 8
Case "Periodic"
ColFinder = 5
Case "Coremap"
ColFinder = 9
Case "ValidTo"
ColFinder = 9
End Select
End Function
Using a few other Functions for finding Last Row & Last Column
Last Row Function
Function lastRow(sheet As String) As Long
lastRow = Sheets(sheet).Cells(Rows.Count, "A").End(xlUp).Row 'Using Cells()
End Function
Last Column Function
Function lastCol(sheet As String) As Long
lastCol = Sheets(sheet).Cells(1, Columns.Count).End(xlToLeft).Column
End Function
With these three functions, you can run a simple loop through the source sheet, one row at a time, then look to see which column the data is coming from, and place it on the appropriate target.
This example is using two worksheets in the same workbook. To change, just extend the address to include other workbooks or sheets. This is just the simplest way to show the concept.
CODE TO LOOP THROUGH SHEETS
Sub ColsToRows()
Dim tRow As Long, sCol As Long, sRow As Long
Dim source As String, target As String
Dim tString As String
source = "Sheet1"
target = "Sheet2"
'Set target Row starting point
tRow = 2
'Loop through Source Rows with Data, starting after Header Row
For sRow = 2 To lastRow(source)
'Loop through each header in Source Row
For sCol = 3 To lastCol(source)
'Set Basic Columns on Target
Sheets(target).Cells(tRow, 1) = Sheets(source).Cells(sRow, 1)
Sheets(target).Cells(tRow, 2) = Sheets(source).Cells(sRow, 2)
'Get Header Name as Temp String to find which format it requires
tString = Sheets(source).Cells(1, sCol)
'Label Column 3 of Target
Sheets(target).Cells(tRow, 3) = Sheets(source).Cells(1, sCol)
'Find Appropriate Column using custom Formula [ColFinder(header As String) As Long]
Sheets(target).Cells(tRow, ColFinder(tString)) = Sheets(source).Cells(sRow, sCol)
'Advance to next Target Row
tRow = tRow + 1
Next sCol
Next sRow
End Sub
Source Sheet Example
Target Sheet Example
You can convert the upper table to the lower one using formulas within Excel.
We start from defining all the input range, without the first 2 columns and the headers row as a range named input. This is done by selecting all the range and typing "input" in the "Name box":
Create the following table where you like in the workbook, then define it all and a range named col_index:
STRINGVALUE INTEGERVALUE FLOATVALUE FLOATVALUEWITHUNITS BOOLVALUE TIMEVALUE URLVALUE REFERENCEVALUE
NameLegacy ProjectNumber External Coremap OwnerSite Content
OwnerName Periodic Relevance ValidTo
Language
Keywords
This table basically sorts the original columns into their new place. You can add values, rows or columns to the table and it will stay intact, as long as you keep all of it under the name range col_index.
Then create another table headers:
ID Version IBANAME STRINGVALUE INTEGERVALUE FLOATVALUE FLOATVALUEWITHUNITS BOOLVALUE TIMEVALUE URLVALUE REFERENCEVALUE
Now paste the following formulas in the first row in each of column 1-4:
ID: =IF(C2=sheet1!$C$1,A1+1,A1)
Version: =VLOOKUP(A2,sheet1!$A$1:$B$4,2)
after selecting the first 12 rows under IBANAME, press F2, and paste: =TRANSPOSE(sheet1!C1:N1) as array formula! (press ctrl+shift+enter after pasting to the formula box)
STRINGVALUE: =IF(ISERROR(MATCH($C16,OFFSET(col_index,0,MATCH(D$15,OFFSET(col_index,0,0,1,11),0)-1,5,1),0)-1),"",OFFSET(input,TRUNC((ROW()-ROW($D$16))/COLUMNS(input)),MOD(ROW()-ROW($D$16),COLUMNS(input)),1,1))
Next, drag columns ID and Version 12 rows down, to the next ID (row 14), then change the value in cell A2 to 1, and the value in C14 to =C2, and continue dragging columns ID, Version and IBANAME until the end of the data is reached. Finally, drag the cell D2 left to the end of the row, and then down to fill all the table.
This it how it looks with formulas:
And this is with values:
That's it ;)

Transpose columns into new column and maintain/duplicate rows accordingly

Apologies for awkward title. I have searched through the forums but not yet come across a solution which is appropriate. I imagine what I am after will require the use of a macro.
I have a spreadsheet which outlines transactions by row, that is, one row for each transaction. Each transaction contains projected financial data. So, each row relates to one transaction which has financial impacts across multiple years.
For example, the header looks like
Transaction | field1 | field 2 | etc. | 2010-11 | 2011-12 | 2012-13 | etc. |
Beneath the years are dollar amounts.
All the fields contain data I need replicated across rows, except I want the year transposed into a single column, with the financials against it.
So if I have the record:
exampleid | data | data | 45000 | 56000 | 223145 | data
I would like it too become:
exampleid | data | data | 2010/11 | 45000 | data
exampleid | data | data | 2011/12 | 56000 | data
exampleid | data | data | 2012/13 | 223145 | data
There are around 30 columns.
You don't need VBA. You can use/adapt the formulas posted here.
That post was intended precisely as a reference for cases like this one.
For each of your input rows, you need two sets of formulas row-to-column, one for the headers and one for the data.
Use appropriate relative/absolute indexes in formulas, to be able to copy/paste.
Here's what I use to do this. You can change the variables at the start of the sub to dictate how many columns you have with data, how wide your pivoted data is, which sheet names are used for the import and the export, etc etc.
The exported data will always start at the same column that the original data started at.
The data needs to have headers to work correctly, and it assumes there are no blank cells in the first column of data.
Sub pivot_data()
data_sheet = "Sheet1" 'name of sheet containing original data
export_sheet = "Sheet2" 'name of sheet to export to
start_d_row = 2 'first row of data (headings are grabbed from row above)
start_d_col = 1 'first column of data
end_d_col = 7 'last column of data
start_t_col = 4 'first column to pivot
end_t_col = 6 'last column to pivot
xrow = 2 'first row to export DATA to (headings will be row above)
trailing_col = end_d_col - end_t_col 'calculated number of trailing columns
pivot_size = end_t_col - start_t_col + 1 'calculated size of pivot
'headings
For xcol = start_d_col To start_t_col - 1
Worksheets(export_sheet).Cells(xrow - 1, xcol).Formula = Worksheets(data_sheet).Cells(start_d_row - 1, xcol).Value
Next xcol
Worksheets(export_sheet).Cells(xrow - 1, xcol).Formula = "Narrative"
Worksheets(export_sheet).Cells(xrow - 1, xcol + 1).Formula = "Value"
For xcol = start_t_col + 2 To start_t_col + 2 + trailing_col - 1
Worksheets(export_sheet).Cells(xrow - 1, xcol).Formula = Worksheets(data_sheet).Cells(start_d_row - 1, xcol - 2 + pivot_size).Value
Next xcol
'data
For irow = 2 To Worksheets(data_sheet).Cells(start_d_row - 1, start_d_col).End(xlDown).Row
For icol = start_t_col To end_t_col
For xcol = start_d_col To start_t_col - 1
Worksheets(export_sheet).Cells(xrow, xcol).Formula = Worksheets(data_sheet).Cells(irow, xcol).Value
Next xcol
Worksheets(export_sheet).Cells(xrow, start_t_col).Formula = Worksheets(data_sheet).Cells(1, icol).Value
Worksheets(export_sheet).Cells(xrow, start_t_col + 1).Formula = Worksheets(data_sheet).Cells(irow, icol).Value
If end_d_col = end_t_col Then
Else
For xcol = start_t_col + 2 To start_t_col + 2 + trailing_col - 1
Worksheets(export_sheet).Cells(xrow, xcol).Formula = Worksheets(data_sheet).Cells(irow, xcol - 2 + pivot_size).Value
Next xcol
End If
xrow = xrow + 1
Next icol
Next irow
End Sub
Hope that helps
VBA can certainly be used to solve this problem but for regularly structured data such as this native Excel alone can also be used.
The basic problem is that you want to split each record in your "input" list into n records in your "output" list. So if you have i records in your input list you will have i*n records in the output.
I used to do a lot this sort of stuff on the UK Office for National Statistics population data, where the data was published in neatly formatted tables showing population levels by age group and location whereas I wanted it in a list format with each record showing just the population in a single location and age group combination. The list format was often then used either with Excel's data filtering and/or Pivot tables for analysis purposes and occasionally imported into Access.
The approach to transforming the data is as follows.
Assuming for example you have 25 years worth of data in your input table and say 200 input records, you want to generate 200*25=5000 output records so first generate a 2 column list of with 5000 rows. Start with 1,1 in the 1st row; 1,2 in 2nd row; 1,3 in 3rd row; ... ;1,25 in 25th row; 2,1 in 26th row; 2,2 in 27th row; ... ; 2,25 in 50th row; 3,1 in 51st row; and so on until you reach 200,25 in the 5000th row. Such a list is easy enough to generate: assuming cells A2 and B2
represent the first 1,1 (simply type these values into the two cells) then B3 has a formula such as
IF(B2=25,1,1+B2) which can be copied down the remaining rows of
column B. A3 also contains a formula based on the IF function, but this time
the first argument is based on the value in the adjacent cell (ie B3). The precise formula is left as an exercise and, again should be copied down the remaining rows of column A.
The 5000 rows correspond to your output records and each pair of values tells you which input record (first value) and which year within that record (second value) provides the data for the output record. You now have a choice of functions for using this information to create cells containing the output records. Possibilities include the INDEX(), OFFSET() and INDIRECT() functions though the latter will need to be used in conjunction with the ADDRESS() function.
INDEX() is probably most straightforward to understand and apply but the others are worth exploring and understanding. If your 200 input records, not including the header row, is held in say Sheet1!A2:AB201 (with cols A-C used for the non-year data and the 25 years of yearly data being in columns D-AB) and the output table is to appear on Sheet2 (with row 1 being a header row and columns A and B being used as described in step 1., above) then the formula for Sheet2!C2 would be =INDEX(Sheet1!A$2:A$201,$A2) and this formula can be copied both for all output rows and the next 2 (non-year) output columns (note the use of mixed absolute and relative addressing that achieves this). The year value for the 4th column of the output list (column F) is generated by picking out the correct value from the header row in Sheet1. The formula to use is =INDEX(Sheet1!$D$1:$AB$1,B2) in cell Sheet2!F2. Copy this formula down the remaining rows of column F. The formula for cell Sheet2!G2 uses the two dimensional version of the =INDEX() function - but I'll leave that one as an exercise. Once you've got the correct formula it should be copied down the remaining rows of column G.
If you have navigated the above successfully your output data should be in Sheet2!C2:G5001 and you can type your column headers into row 1.
One final comment on your terminology. You are not transposing your data, instead you are transforming the way it is presented. Transposing data usually means converting all the rows of a table into columns and vice-versa: so a table with I rows and J columns is transposed to become a table with J rows and I columns. In your case, the dollar values are transformed from I rows and J columns to I*J rows and 1 column.

VB Script- read excel column values and assign it a dynamic array and form different sets of combinations of data

I have a requirement to form a permutation data from the given set of values in excel sheet. Below are the details.
Let us say there are 5 columns and each column has some rows of data as below in input excel sheet.
Column 1 - 2 values(ind,us)
column 2 -1 value (a1)
Column 3= 3 value(cat,dog,cow)
column 4= 4 value(1,2,3,4)
Column 5= 1 value(d)
The output excel has to be on below format.
ind,a1,cat,1,d
ind,a1,cat,2,d
ind,a1,cat,3,d
ind,a1,cat,4,d
ind,a1,dog,1,d
ind,a1,dog,2,d
ind,a1,dog,3,d
ind,a1,dog,4,d
ind,a1,cow,1,d
ind,a1,cow,2,d
ind,a1,cow,3,d
ind,a1,cow,4,d
us,a1,cat,1,d
us,a1,cat,2,d
us,a1,cat,3,d
us,a1,cat,4,d
us,a1,dog,1,d
us,a1,dog,2,d
us,a1,dog,3,d
us,a1,dog,4,d
us,a1,cow,1,d
us,a1,cow,2,d
us,a1,cow,3,d
us,a1,cow,4,d
please note the rows and column count are not constant.
Request all to give some thoughts to implement.
Thanks,
Rakesh
See this question for ways to get (all) combinations of elements with specified values for each slot. Just feed your data as an array of arrays to the Permute function or the .init method.

Resources