Been searching around and got a bit confused.
I have a sheet (herein called "ModelSpec") filled with data of TVs with a header that starts at A5:Z5 (Example Header Title is "Part Number", "Brand", "Size", "Resolutions"...etc). Some are with data, some are blank cells.
I'd created some USERFORM to allow user to select how they want to search for their Model Specification.
What I'm trying to do now is to pick up a data ("Part Number") located in the USERFORM textbox that the user selected and do a search in the "ModelSpec" sheet for the Part Number (located in Column A6:A?). The number of rows of data may change and I guess we need a FOR loop to stop at empty rows.
Once found, the entire row will be copied and paste value only on A1:Z1 of the same ModelSpec sheet.
So basically I'm currently working on Private Sub within the FORMS and not MODULES.
From there I have another code to extract the details to a form else where.
Please help this confused man.
This is a starting point for you, and has all the elements you'd need to do what you are asking.
What's Happening:
Click event on the userForm launches this code
Get the last row of the sheet containing data
Loop through all rows
Compare the value of txtPartNumber to the value in Column A of the current row in the loop.
If a match is found, display message confirming and copy the row being searched to row 1 of the same sheet.
If no match found, display message.
notes:
There is no handling of user input error. No upper case to lower case, or dropdown box limiting the user's choices. A good thing to do (in another question) would be to create a dynamic drop down or comboBox, that is populated by already existing part numbers, limiting the user input error.
If there is more than one match on the page, it will loop through all of the rows and copy the match to row 1. Then copy over row 1 with any match found after that, so the LAST one will be the only one you see. If you want it to only match the FIRST, then include an End statement right after copying the search row to row 1. I'm assuming your search column has unique IDs / part numbers.
Code:
Private Sub cmdSearch_Click()
Dim lastRow As Long, lCol As Long, lRow As Long
Dim sName As String
sName = "ModelSpec"
lastRow = Sheets(sName).Range("A" & Rows.count).End(xlUp).row
For lRow = 6 To lastRow
'Check to see if A(lRow) = TextBox. Exact match required
If Sheets(sName).Cells(lRow, "A").Text = txtPartNumber.Text Then
MsgBox("Match Found for Part #: " & txtPartNumber.Text)
For lCol = 1 To 26 'Loop through columns A-Z, Copy lRow to Row 1
Sheets(sName).Cells(1, lCol) = Sheets(sName).Cells(lRow, lCol)
Next lCol
Else
MsgBox("No match found for Part #: " & txtPartNumber.Text)
End If
Next lRow
End Sub
Related
I have a table in Excel like such, where the number of rows will vary each day:
Column A
Column B
Column C
Cell 1
Cell 2
Show
Cell 3
Cell 4
Show
Cell 5
Cell 6
Ignore
I am using vba to convert the range to a html table, and then email it.
I have a helper column (Column C), and I want to use a formula there to filter out certain rows.
However, that filter is not excluding hidden cells from being displayed in the html table.
I currently use this
Dim LastRow As Long LastRow = rInput.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
to find the last row of my table. This works great in projects where you want all of the table included.
I tried to change it to Find("Ignore", which gets me Object variable or With block variable not set
I tried including 'SpecialCells(xlCellTypeVisible)' in my
ConvertRangeToHTMLTable(Sheet2.Range("$A:$J").Rows("5:" & LastRow), 5)
and using a filter to hide the 'Ignore' cells. But that did not stop them showing in the emailed html table.
You probably have some sort of loop which goes over the rows right? It will not automatically skip the hidden rows just because they are filtered out, you need to specifically tell it to skip them. You can do something like:
For Each r In myRange.Rows
If Not r.EntireRow.Hidden Then
doSomething
End If
Next r
Ended up adjusting the table (and thus the range I cared about) to start at row 1 rather than row 5, and using
strBody = dsaEmailHeader & ConvertRangeToHTMLTable(Sheet2.Range("$A:$H").Rows("1:" & LastRow).SpecialCells(xlCellTypeVisible))
worked, where it didn't previously.
I have looked at similar questions but they don't seem to fit my problem. I have two sheets in excel; one has a type of header/overview data for some tasks, the other has several lines of details for each task.
I need help writing a macro that will match the Task ID between the two sheets and copy the entire row of header data from sheet one into a blank row above the group of detail rows in sheet two.
(Before this code will run, I will run a macro that will insert a blank line between each group of detail data. When I get this working, I will combine the two pieces of code.)
The copy statement is where I am stuck. It returns Application defined or object-defined error.
Sub InsertMWITitles()
‘copies the MWI titles above the correct MWI Steps group
Dim lngLastRowSht1, lngLastRowSht2, counterSht1, counterSht2As Long
With Worksheets(“MWI Titles”)
lngLastRowSht1 = .Cells(.Rows.Count, 8).End(xlUp).Row
lngLastRowSht2 = Worksheets(“MWI Steps”).Cells(Worksheets(“MWI Steps”).Rows.Count, 1).End(xlUp).Row
For counterSht1 = 1 To lngLastRowSht1
For counterSht2 = 1 To lngLastRowSht2
‘if the Task ID in column H of the MWI Titles sheet matches the Element ID in column A of
‘the MWI Steps sheet, copy the entire title row to the steps sheet above the group
If Worksheets(“MWI Titles”).Range("H" & (counterSht1)).Value = Sheets(2).Range("A" & counterSht2).Value Then
Worksheets(“MWI Titles”).Range("A" & (counterSht2).EntireRow.Copy Sheets(“MWI Steps”).Range("A" & (counterSht2 – 1))
End If
Next counterSht2
Next counterSht1
End With
End Sub
I also tried to copy and insert with shift down, but couldn't get that to work either.
The top section of the sample data is sheet 1/MWI Titles (the header data) and the bottom section is sheet 2 /MWI Steps (the detail data).
Sample of data in both sheets
I have 2 worksheets (WS1 is "ImportWS" and WS2 is "Disco + BLScope", there are names in column A in both worksheets and both have a column B with a value like Jumps high or still cant jump high). I need to compare WS Disco + BLScope column A with ImportWS Column A and if a match is found then copy the adjacent value in WS ImportWS Column "B" to WS Disco + BLScope Column "B" on the respective matched row and then continue to see if there are more updates in WS ImportWSand repeat.
In a perfect-world, a pop up would appear at the end stating how many updates were found/made.
I have tried Vlookups but that doesn't work as I want to keep the value in WS Master if a match is not found.
I found this code (which does the core of what I need) which I tried to adjust but I get a run time error on the "lassrowAdd" line:
Sub CopyAdjacent()
Dim colStatus, lastrowAdd, lastrowRemove As Integer
colStatus = 2
lastrowAdd = Sheets(“ImportWS”).Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lastrowAdd
If Sheets(“ImportWS”).Cells(i, 1).Value = Sheets(“Disco + BLScope”).Cells(i, 1).Value Then
Sheets(“Disco + BLScope”).Cells(i, colStatus).Value = Sheets(“ImportWS”).Cells(i, colStatus).Value
End If
Next
End Sub
So basically the end result would be:
The worksheet Disco + BLScope would have an updated value in the respective column B rows if an update is found in worksheet ImportWS.
At the end of the macro a popup to appear (this is totally optional) stating how many updates were found/made.
Hope that made sense, been trying for hours but cant crack it, your help would very much be appreciated.
I am trying to do an incremental numbering in Excel, but for a specific condition. If the condition does not match, then it should keep the existing cell details.
Image:
As you can see from the picture, I want to create a numbering list in column B, which is based off information shown in the corresponding row in column D. So on the second row, I would the counting to start at "1" and then continue to expand only as the count of "is_null" and "equal" grows. At the same time, I want it to skip over the green and blue cells and keep the contents as is.
As of right now, I have done the following formula:
=COUNTIF($D$1:D2,"is_null")+COUNTIF($D$1:D2,"equals")
This does the proper numbering, however it over-writes the green and blue cells instead of keeping them as "A" and "stop" respectively.
If someone can help me with that issue, then I should be good to go. Thanks!
I'm not sure what the value should be if in Column D you find the String "set_path" or "stop", but if these are always the same (i.e. "a" if Column D = "set_path" and "stop" if Column D = "stop"), you could achieve your desired results with the following formula:
=IF(AND(D2<>"set_path",D2<>"stop"),COUNTIF($D$1:D2,"is_null")+COUNTIF($D$1:D2,"equals"),IF(D2="set_path","a",IF(D2="stop","stop","")))
UPDATE:
Using VBA you could leave the contents of the cell as they are without overwriting them with a formula using the code below:
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set the worksheet you are working with, amend as required.
Dim LastRow As Long, i As Long
LastRow = ws.Cells(ws.Rows.Count, "D").End(xlUp).Row
'get the last row with data on Column D
For i = 2 To LastRow
If ws.Cells(i, "B").Value = "" Then 'if cell is empty add formula
ws.Cells(i, "B").FormulaR1C1 = "=COUNTIF(R1C4:RC[2],""is_null"")+COUNTIF(R1C4:RC[2],""equals"")"
End If
Next i
End Sub
Second Update:
I've now adapted the formula to increment the letters by one if "set_path" is found in Column D (Please bear in mind that this will go from A-Z and then it will start going through symbols as per ASCII table, so you might have to amend this if you want alternate behavior):
=IF(AND(D2<>"set_path",D2<>"stop"),COUNTIF($D$1:D2,"is_null")+COUNTIF($D$1:D2,"equals"),IF(D2="set_path",IFERROR(CHAR(COUNTIF($D$2:D2,"set_path")+64),""),IF(D2="stop","stop","")))
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.