Problem:
I would like to find a value of a cell next to or below the cell content a text value for a workbook.
Example:
In Sheet2, I have two cells stand random (assume its index is unknown and total is not a defined name)
I want to search for the value "200" stands next to the total and put it in sheet 2 (an active cell). In case, there are multiple cell that contains the word "Total" list all of them and if possible, put the name of the sheet that contains the cell that I am looking for. Value 200 Sheet2
My Approach:
1. User input
Go to each cell and search for it. This will take time if search for the whole limitation of cell in excel. So the search only limit to 100 columns x 10000 rows.
After find its index, offset to 1 columns to get the value
Write the result ActiveCell.Value = Search_Value. Then continue to search for the rest of sheets. Offset 1 coloum and 1 row to write the second value...
Searching is a very difficult concept, and I truly have no idea how to do the search part. Please help
With Worksheets(1).Range("a1:a500")
counter=0
Set c = .Find("Total", lookin:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Address
Do
counter=counter+1
Worksheets(2).range("A1").offset(counter,0)=c.offset(0,1)
Set c = .FindNext(c)
Loop While Not c Is Nothing And c.Address <> firstAddress
End If
End With
firstaddress holds the location of the first cell found (so we know when to stop); firstaddress.offset(0,1) will give you the value you are trying to save, so setting worksheet(2).range("a1").offset(counter,0) will list all the values it finds on the 2nd tab, from a1 down to however many it finds in the range
Related
I copy a lot of information (1000 rows and at least 24 columns) from one sheet to another. A lot of the cells contains "". This makes my other formulas(for example: A1-B1) to show an value error if either of these cells contains "".
I believe I can solve the problem by never pasting "" but a "0" instead. But I would like to delete these "0" afterwards.
There could be values in the first 3 rows but the other 997 rows have "".
I would think I need to tell my macro to (Cell A1 in the "sheet1" sheet displays "G5:H12". the cells I need to delete):
Rowstodelete = Sheets("sheet1").Range("A1").Value
Sheets("sheet1").Range("rowstodelete").clearcontent
This does not work. anyone know how to do this?
Summary(new example)
If cell A1 = "B1:B2" I want to clear the content of B1 and B2, but if A1 now = B4:B6, that is the cells that should be cleared.
Try this one:
With Worksheets(1).Range( _'PLACE YOUR RANGE
)
Set c = .Find(0, lookin:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Address
Do
c.Value = ""
Set c = .FindNext(c)
Loop While Not c Is Nothing
End If
End With
Hope it helps
Anyhow, I think that will be simpler to place a condition in your operation formula: =IF(OR(A1="",B1=""),Make when there is an unexpected value,A1-B1)
I have an issue with using a formula that contains a fixed cell in VBA. The issue comes when the row number of the variable in the new data changes.
The issue is explained using a simple example as follow. I hope you find it understandable.
Let's say I have a column of numbers (Time) and I want to multiply them by a variable in a cell (The cell below Variable in the following table, $A$2).
First result from first raw data:
The results in the table are calculated using the following formula "=R2C1*RC[-1]" in vba
Now in the next calculation, the row number and variable change and the part of the formula which is using a fixed cell cause problem.
Second raw data to be processed
Because it does not update the row number and use the old row number. I want it to find its location like the second part of the formula (B2 changes to B7).
Thank you for your help!
Cheers,
Aryan
you should reference the found cell row in your formula
ActiveCell.FormulaR1C1 = "=R" & ActiveCell.Row + 1 & "C1*RC[-1]"
but you should also avoid the Activate/ActiveXXX/Select/Selection pattern since is prone to have you quickly lose control over the actually active thing
finally you an use a loop to find all "Time" occurrences (see Here for more info about the pattern)
Option Explicit
Sub main()
Dim f As Range, firstCell As Range
With Worksheets("myWorksheetName") ' reference your worksheet (change myWorksheetName to your actual sheet name)
With .Range("B1", .Cells(.Rows.Count, "B").End(xlUp)) 'reference its column B cells from row 1 down to last not empty one
Set f = .Find("Time", LookIn:=xlValues, lookat:=xlWhole) 'search referenced range for first occurrence of "time"
If Not f Is Nothing Then ' if found...
Set firstCell = f ' store first occurrence cell
Do
f.Offset(1, 1).Resize(4).FormulaR1C1 = "=R" & f.Row + 1 & "C1*RC[-1]" ' populate the range one column to the right of found cell and 4 rows wide with the formula containg the reference of found cell row +1
Set f = .FindNext(f) ' serach for the next "Time" occurrence
Loop While f.Row <> firstCell.Row ' loop till you wrap back to initial occurrence
End If
End With
End With
End Sub
The notation R2C1 is an absolute reference to row 2, column 1.
If you want a reference that is relative to the current cell, you need to use relative reference notation.
RC[-1] points to a cell in the current row and one column to the left
R[1]C points to a cell one row down from the current cell and in the same column as the current cell.
Google for "R1C1 reference". You will find many articles, for e.g. https://smurfonspreadsheets.wordpress.com/2007/11/12/r1c1-notation/
I am very new to VBA and need some guidance here. I have found little snippets here and there but can't seem to figure out how to place them all together.
The overall script looks at a specific cell to see what store number is being worked on, then goes to a different sheet to find that number in row 2. On this other sheet, Column C contains all possible items for the stores in the region. Once the store number is located in row 2, that column is now important as it lists "Delete" or "Add/Retain" for the previously mentioned items listed in Column C.
At the point in my script where I am at, I have the header cell active, on sheet2, that is the store number. Below it lists whether the products going down column C should be "Delete" or "Add/Retain".
I am looking for help on how to search the active column for "Delete" and "Add/Retain" then momentarily transfer the product number from column C to a variable that can be used externally.
For example, let's say the store number corresponded to Group 3. This is located in Column F on Sheet2. Below it is a specific/unique set of "Delete" or "Add/Retain". The first item down says "Delete", so the script should go to column C in which it will find item number "51308". It sets a variable to this value then passes it to my external program where it searches the database for that number (51308) and removes it since it was a "Delete". It writes this action to a text file "Deleted item 51308 from Group 3". Now the script moves down another row and there is "Add/Retain" listed. Back to column C (product list) and it lists "74063". The temporary variable gets set to this new product number, gets passed to my program, the database is checked to see if the number is currently there, if it is, nothing happens, if it isn't, it gets added and the text file is written a new line of "Added 74063 to Group 3".
That's it. Easy right!?
This is a screenshot of the Sheet2 I was mentioning.
So far I have this:
Dim rng1 As Range
Dim strSearch As String
strSearch = "Delete"
Set rng1 = Range("D:D").Find(strSearch, , xlValues, xlWhole)
If Not rng1 Is Nothing Then
Set rng2 = rng1.Offset(0, -1)
MsgBox rng2
MsgBox "Find has matched " & strSearch & vbNewLine & "Corresponding cell is " & rng1.Offset(0, -1)
Else
MsgBox strSearch & " not found"
End If
The script finds the first "Delete", then goes back one column to column C and displays the item number. I could then pass this on to my program no problem.
This is ok except the store group could be anywhere on Row 2 (not just column D).
Experiment first with the use of the Match and index functions. The match function to locate the row the matching store number is found on, and the index function to return the values from each of the other columns. this would allow you to join the data from two sheets onto your first worksheet for processing.
By putting the match function on sheet1 to locate the matching row on sheet2, you can then write your vba to loop down the column with the match function in it to then read across the columns to check the values or assign them elsewhere. Using loops vs. the Find function will allow you to navigate from one cell to the next efficiently and overcomes the limitation of not being able to easily find the next value you are looking for.
I need assistance finding the next instance of an exact string within a cell.
To be precise, I want to look through a series of headings and find the next instance of a declared variable to obtain the column number, and I want to look through that series of headings to find the next empty cell and save that number, and finally, I'd like to take that first column number, and search from second row until I find the first instance of an empty cell, and save that number into a variable. What I have been doing is this:
With Rows(1)
Set found = .Find(what:=Target, After:=.Cells(1, 1))
End With
But it seems that if I accidentally type "s" it will find the first instance of a cell that contains a string that contains the substring "s" (LastName), and not the first cell that contains only "s".
my fear is that if there are columns with " " in them then my program will not function correctly.
Besides that, I sort by a column and when a cell in that column is empty my program pushes it all the way to the bottom of the list and I am trying to delete that empty cell space.
I tried doing Application.WorksheetFunction.Match, HLookup and VLookup and in general the worksheet functions aren't working for me.
So just to give an example of what I want to do:
I have 10 Columns with headings. I want to find the first instance of a column that
contains exactly the string I send into this class. For instance, if the
columns are "FirstName | LastName | Name", I want it to return "Name"
and not "FirstName".
I want to find a column that the user requests as a sort key and verify it's existence
I also want to find a column that is empty (last column)
Finally, I want to find the last row that has a value in relation to the SortColumn.
If you set the lookat parameter to xlWhole, it will only match the whole contents of the cell, so for example:
With Rows(1)
Set found = .Find(what:=target, After:=.Cells(1, 1), lookat:=xlWhole)
End With
To check whether a value was found, you can check whether found is nothing.
Dim exists As Boolean
If Not found Is Nothing Then exists = True
To locate the first empty cell at the end of a row or column of values, I would use the End property to find the last cell in the row/column containing data, then use Offset to find the next cell:
With Rows(1)
Set found = .Find(what:=target, After:=.Cells(1, 1), lookat:=xlWhole)
End With
Dim emptyCell As Range
If Not found Is Nothing Then
Dim col As Integer
col = found.Column
Set emptyCell = Columns(col).End(xlDown)
emptyCell.Offset(1, 0).Select
End If
However, you can't use this if there are some empty cells in the middle of your table of values. (eg if you have values in A1,A2,A3, then A4 is blank and you have more values in A5,A6,A7).
You can use a do loop:
headerToFind = "Name" 'or whatever header you're looking for
x = 1 'or whatever header row is
y = 1 'or whatever first column with header is
Do Until Cells(x,y) = ""
If Cells(x,y) = headerToFind then
MsgBox "The header you are looking for is in row " & x & ", column " & y
Exit Sub
End If
y = y + 1
Loop
MsgBox "Header not found"
In place of the message boxes, put whatever code you want to do with what you find. The first MsgBox will execute if and when the header is found (with x being equal to the row number and y being the column number). The second MsgBox will execute if the desired header is not found.
I've got an amount of data copied from a table in a .pdf that when pasted into excel puts it all into one column. There are actually multiple pages each with it's own table (the data is one continuous long table split over multiple pages more accurately) and at the top of each page is a series of lines that I'm not interested in (the same unwanted data is at the top of each page). What I am interested in is re-sorting the data under the headers as it is in the table on the original .pdf document, removing the headers in the process. The data as it has been pasted into one column essentially is a list of items in plain text for x rows, followed by a list of start dates for x rows, and then a list of end dates for x rows, repeated every page.
I've figured out how to count the number of lines I don't want by getting a macro to look for the first piece of data I'm interested in ("AAAA") starting at cell (B2);
Cells(2, 2).Select
For i = 1 To 50
If ActiveCell = "AAAA" Then
Exit For
End If
ActiveCell.Offset(1, 0).Select
Next i
Cells(2, 3) = i
If i = 51 Then
Range("B3") = "Cannot find data"
End If
Which starts a search at cell (B2) looking downwards until it finds "AAAA" it then prints how many rows it has moved downwards to find it in cell (C2).
I now wish to be able to start at the cell it has just found [(B34) in this case] and count downwards until it finds the first cell containing a date.
Ultimately I'll need to then count down the same number of cells to find the associated end date and print them all in one row, continuing for the entire column of data.
If anybody could help me with being able to start at the first cell "AAAA" and then count downwards until a date is found, that would be really helpful.
My biggest challeng is to understand what you want to be true. I tryed to make a list of the things what you want.
You have a PDF that when paste in Excel it transform all the
document in one column.
There is a header in each of the Excel pages that you want to delete.
After you find a header you want to find two dates, and they have the same distance from the header.
How I would do it:
For iCounter = 1 to Cells(1048576, 1).End(xlUp).Row
If Cells(iCounter,1) = "YOUR HEADER HERE" then
For kCounter = iCounter to Cells(1048576, 1).End(xlUp).Row
If IsDate(Cells(kCounter,1)) = true then
initialDate = Cells(kCounter,1)
endDate = Cells(2*kCounter-iCounter,1)
End if
Next kCounter
End if
Next iCounter
The following piece of code starts in cell A1 and searches downward until it finds a cell containing a date value. The code only searches until it reaches the last record in the first column (to avoid searching all the way down to the bottom of the sheet if no date is found).
Sub FindFirstDate()
Dim i As Long
For i = 1 To ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
If IsDate(ActiveSheet.Cells(i, 1).Value) = True Then Exit For
Next i
MsgBox "The first cell with a date is " & ActiveSheet.Cells(i, 1).Address
End Sub
In this example the address of the cell with the first date in returned in a MsgBox.