Find out if a column contains a certain number - vba

Right now I have a macro that loops through a worksheet that contains data about different machine parts performs various actions on another worksheet using that data. Now I want it to add each part number to a column in a third worksheet, but only if it doesn't already exist there. Here is my code for adding the part numbers:
Rows("1:1").Insert Shift:=xlDown
Range("A1").Value = cpn
I have the list spoted after each added part number. Is there any way better than a loop to find out if the part number already exists?

You could use the COUNTIF method. Just like this:
Application.CountIf(Range("A:A"), valueThatYouWantToSearchFor)
It will return the number of cells that contains this value.

Related

Search xlsx for a value, if found replace with different value

So I'm either being too specific, or not searching well enough, because I can't find anything that answers my question. So I came here for help. Here is the situation:
I have an excel sheet, let's call it "CustomerCodeReference", that has a column (A) of Customer Codes (I.E. A2001, A2002, B3900, Q2838, etc, these are NOT necessarily in order) About 3000 of them, and in the next column over (B), I have the group that code represents (I.E. Accounts Primary, Accounts Secondary, Admin Group, User Group, just different names and etc.)
Now, from our company server I can export a spreadsheet of reports from customers, but the problem is, they are labelled by customer code, + a report serial number. The sheet exports as several columns, but one of the columns (G) contains the Customer code and serial number, and each row is a report, sometimes hundreds depending on the date range set. So keeping with the example, let's say it's a report from "Accounts Primary" It's labelled A2001234567 (where everything after the customer code of 'A2001' is the report serial number) sometimes, the report may be from several customers, so that column may have more than one code+SN in it per row.
Given that I have thousands of these codes and groups, is there some macro I can create that every time I export the spreadsheet of reports, I can maybe copy over the "CustomerCodeReference" sheet, and have it automatically search the column of customer codes and SNs, then either replace the code with the actual name, or place the actual name in another (empty) row further back. So I can basically easily reference whose report it is without having to look up the code each time?
I realize I will need to do this in VBA, as there is no formula I can think of that will work.
I have some pro's I think going for me:
-I already have the Master code list, so even though there are thousands of codes, they are all listed in Column A, and the actual name of group they reference is in column B.
-The codes are consistent, a letter, followed by 4 numbers, so always 5 characters long.
-When pulling the report, it always names the worksheet "Customer Reports" so it's easy to reference
These are constants. So I need the actual customer name to either replace the code (while leaving the serial number intact) or if easier, add the actual name to the next empty column on the same row. I also might need to share this with coworkers, so basically just send them the "CustomerCodeReference" sheet and when they add it to all their pulled spreadsheets, it does the same thing. (Macros will be enabled, so no worries there)
Is this too complicated an idea? or can I pull it off? Thanks in advance for the help!
EDIT: I apologize, I complete forgot to attach any sort of code. Here is what I have come up with in VBA, but not sure if I am on the right track as it does not complete the replacement, and I can't quite get it to add values in next available empty cell.
Sub replaceStringInCell()
'declaring my sheet I want to change change customer codes in
Dim CustomerCodes As Range
'declaring strings I will be replacing and with what I will be replacing them
Dim ReportNumbers As Range
Dim CustomerNames As Range
'identifying column I am working to replace, also trying to shoot for next empty column
Set CustomerCodes = PulledReports.Worksheets("Customer Reports").Range("G:G")
'specifying my strings
ReportNumbers = PulledReports.Worksheets("Customer Reports").Range("G:G")
myReplacementString = PulledReports.Worksheets("Customer Code Reference").Range("A:A")
'replace string in cell
CustomerCodes.Value = Replace(Expression:=CustomerCodes.Value, Find:=ReportNumbers, Replace:=CustomerNames)
End Sub
This should do the trick:
Sub stack_overflow()
Dim cust As Worksheet
Dim ref As Worksheet
Set cust = ActiveWorkbook.Worksheets("Customer Reports")
Set ref = ActiveWorkbook.Worksheets("Customer Code Reference")
'Finding next empty column
Dim column As Integer
column = cust.UsedRange.Columns.column + 1
'Filling this columns
For Each cell In cust.Range("G2:G" & cust.Cells(Rows.Count, "G").End(xlUp).Row)
cust.Cells(cell.Row, column).Value = Application.WorksheetFunction.VLookup(Left(cell.Value, 5), _
ref.Range("A2:B" & ref.Cells(Rows.Count, "B").End(xlUp).Row), 2, False)
Next cell
End Sub

I would like to match the data of two columns in two different excel workbook

I have two excel WORKBOOK (WB)
In excel WB 1, I have column for student IDs and Advisor name.
In excel WB 2, I have IDs to be matched to WB 1 IDs if the Advisor name is "John" to show "TRUE' in a column in WB2.
Can you pls tell me what are the formulas to try AND EXPLAIN THE COMPONENTS OF THE FORMULA?
aTTACHED IS THE SCREENSHOT OF DATA.
pLEASE NOTE ITS IN DIFFERENT EXCEL WORKBOOKS NOT SHEETS.
Taking your provided formula I will run you through the minor change that will make this work:
=IF(ISNUMBER(MATCH(C7:C17&"John",'[wORKBOOK1 NAME]SHEET1'!$A$2:$A$13&'[wORKBOOK1 NAME]SHEET1'!$B$2:$B$13,0)),"True","False")
This of course is assuming that the Forenames are in $B$2:$B$13...
What this is doing is simply forming a string value of the ID with the Forname stuck onto the back of it. MATCH will reference an array of values that it creates from the criteria within itself - the ID with the Forename.
The match formula will work in the same way, returning an integer representing the index location within the array when the match is found.
I will point out that the formula does not accept an array for the first argument, so currently only the first cell is being searched... You will want to update the formula and perhaps have this as a column checking each individual ID:
=IF(ISNUMBER(MATCH(C7&"John",'[wORKBOOK1 NAME]SHEET1'!$A$2:$A$13&'[wORKBOOK1 NAME]SHEET1'!$B$2:$B$13,0)),"True","False")
If you wanted this as just one formula it gets a bit more complicated as you must form an array using an if statement and Evaluate against that array:
=IF(ISNUMBER(MATCH(1,IF(C7:C17&"John"='[wORKBOOK1 NAME]SHEET1'!$A$2:$A$13&'[wORKBOOK1 NAME]SHEET1'!$B$2:$B$13,1,0),0)),"True","False")
This must be entered as an array formula (While still in the formula bar hit Ctrl + Shift + Enter)
The if statement will check for the match and build a new binary array (1 for a match and 0 for no match), the MATCH formula then is simply checking if a match is found in that new array by searching for 1.

Referencing a sheet by index number

I've got a LibreOffice Calc spreadsheet that I use to keep track of my accounts receivable at work. Each sheet lists invoices and their status (paid, unpaid, etc) as well as info about each invoice. I'm trying to create a Summary sheet that lists certain data from each sheet. Creating the sheet manually is easy, but I'm trying to "automate" the process. I want the summary page to auto-update if I add a new sheet (or remove one) as I add and remove accounts to the file.
I know that LibreOffice assigns each sheet an index number that I could refer to in some sort of formula, but I cannot find a function that I can use to refer to that index number when getting a value from a cell within it. One would expect that a function like Sheet(2) would reference the second sheet, but, alas, that is not so!
I've tried using the indirect and address functions without success, but I'm not sure if I'm not understanding these functions or if they're not appropriate for what I'm trying to accomplish.
This has been a missing piece in Calc for a long time. The preferred solution is to write a user-defined function. Spreadsheet formulas do not access sheets by index number but Basic can.
The following function is from https://ask.libreoffice.org/en/question/16604/how-do-i-access-the-current-sheet-name-in-formula-to-use-in-indirect/.
Function SheetName(Optional nSheet)
If IsMissing(nSheet) Then
SheetName = ThisComponent.getCurrentController().getActiveSheet().getName()
Else
SheetName = ThisComponent.getSheets().getByIndex(nSheet-1).getName()
EndIf
End Function
Then get a relative address of the first sheet cell A1 like this.
=ADDRESS(1,1,4,,SHEETNAME(1))
A slightly different function is given at https://forum.openoffice.org/en/forum/viewtopic.php?f=9&t=49799.

get multiple column names (header) in table associated with particular value in to a cell

i need to get multiple column names (header) in table associated with particular value in to a cell
as i explained, i need to get the heading names corresponding to value "n" to column E.
i used the formula
=INDEX((A$1:D$1),MATCH("n",A2:D2,0))
here. but it only give one column name.
i am open to vba scripts also. but i think it doesn't need vba. just improve the the above formula, may be. i tried and failed. any help. thank you guys
if you are really "open" to vba, I'll use one simple UDF like:
Function HeatherNames(rg As Range, rf As String) As String
For Each cell In rg
If cell = rf Then HeatherNames = HeatherNames & Cells(1, cell.Column).Value & "-"
Next cell
HeatherNames = Left(HeatherNames, Len(HeatherNames) - 1)
End Function
you can use it in the column E `=HeatherNames(A2:D2;"n") now you can select the arg.1 (range) and type (or referring to another cell) the arg.2
Assuming you have Excel 2010 or later, in E2:
=IF(COLUMNS($A:A)>COUNTIF($A2:$D2,"n"),"",INDEX($1:$1,AGGREGATE(15,6,COLUMN($A2:$D2)/($A2:$D2="n"),COLUMNS($A:A))))
Copy to the right and down as required.
It would actually be slightly more efficient (and certainly if your dataset in reality is quite large) to have the initial IF clause held within its own cell, such that it is calculated for each row only once, rather than for each instance of the formula within that row. So a better set-up would be, in E2:
=COUNTIF($A2:$D2,"n")
copied down. Then, in F2:
=IF(COLUMNS($A:A)>$E2,"",INDEX($1:$1,AGGREGATE(15,6,COLUMN($A2:$D2)/($A2:$D2="n"),COLUMNS($A:A))))
copied to the right and down again.
Regards

Lookup function in multiple sheets data

I have multiple sheets of data and I want to make it in one sheet (All of them are in the same workbook). Link to the excel file.
I tried to use Hlookup function in excel file, something like below:
=HLOOKUP("University",Sheet1!$A$1:$G$2, 2, FALSE).
But, since I have more than 100 sheets of data, I want to find a way to drag the function and auto generate the function below the 2nd row. I have tried to use indirect function by setting a reference column in front as below but cannot deal with it.
=HLOOKUP("University", 'INDIRECT(A3)'!$A$1:$G$2, 2, FALSE)
My next option is VB code. But, I am new to VB. Anybody can help on it?
Place your individual sheet names in column H of the Summary sheet and the row number in column I (as helper columns) and write this formula in cell A2 of the summary sheet.
=IFERROR(HLOOKUP(A$1,INDIRECT($H2&"!A1:G"&$I2),$I2,0),)
and drag to column F and down for as many sheet rows combos you have. I used 10 rows but you can obviously make it longer or shorter as neeed.
When you are done you can filter on 0 in column A and remove any lines with no data.
If your sheet names have spaces in them, you'll need to adjust the INDIRECT formula to this:
INDIRECT("'"&$H2&"'!A1:G"&$I2)
best way would be "defined names" + INDIRECT + HLOOKUP (or LOOKUP) like:
defined names
name: SList
formula: =MID(TRANSPOSE(GET.WORKBOOK(1))&T(NOW()),FIND("]",TRANSPOSE(GET.WORKBOOK(1))&T(NOW()))+1,255)
formula in cells: (this in A2 then simply autofill to G2 and thenn everything down) (you'll get a row with 0's between the sheets, which can be filtered out or deleted later (copy/paste values))
=IFERROR(HLOOKUP(A$1,INDIRECT("'"&INDEX(SList,COUNTIF($A$1:$A1,0)+2)&"'!$A:$G"),$H2,0),"")
Set H2 to 2 and for H3: (autofill down from H3)
=MAX(($H2+1)*($A2>0),2)
works perfectly for me LINK
No manual typing of sheetnames or something like that (only Column H:H as helper). Youll get rows's with 0's every time a new sheet is selected which can be filtered out. (or if you copy/paste values also can be deleted)
the +2 at ...st,COUNTIF($A$1:$A1,0)+2)&... simply tells to start with sheet 2 (if summary is the first). You may change it to +1 if you want to lookup starting with the first sheet.
Assuming you already have all 100+ sheet names typed out in column A, this will work whether or not you have spaces in the sheet names:
=HLOOKUP("University", OFFSET(INDIRECT(ADDRESS(1,1,1,1,A2)),0,0,2,7),2,FALSE)