I'm attempting to create an inventory system at my work as the only software we have as Excel. Basically we have a Work order sheet that we enter the repairs as well as parts used on. I made a code that would pull the inserted part numbers & descriptions out of the individual work orders to keep track of everything used, but my boss wants me to create a system that will allow us to start typing the name/part number of something and have it guess or fill in for us. Hence where the combobox comes in.
I got It working up to a point. The lists are populated with the part inventory (we have a master EXTNERAL file listing) but my issue is this:
When you click the "add part" of the user form, I can't figure out how to have the parts be added in a certain range on the Work Order. All the tutorials I've been following here and here only have it set up to add the parts in order of the column. Can anybody look at my (terrible, I'm sorry) coding and see if they can help?
Private Sub UserForm_Initialize()
Dim cPart As Range
Dim cNum As Range
Dim ws As Workbook
'Dim ComboBox1 As Variant
Application.ScreenUpdating = False
Set ws = Workbooks.Open("\\Capserver\iso maintenance\CAPS MASTER PARTS & PRICE LIST 2012.xls")
Windows("CAPS MASTER PARTS & PRICE LIST 2012.xls").Visible = False
'ws.Sheets("CAPS ORDER FORM").Range("Name") = Sheet1.ComboBox1
'ComboBox1.Clear
For Each cPart In ws.Sheets("CAPS ORDER FORM").Range("Name")
With Me.cboPart
.AddItem cPart.Value
End With
Next cPart
For Each cNum In ws.Sheets("CAPS ORDER FORM").Range("Number")
With Me.cboNum
.AddItem cNum.Value
.List(.ListCount - 1, 1) = cNum.Offset(0, 1).Value
End With
Next cNum
End Sub
Private Sub cmdAdd_Click()
Dim lRow As Range
Dim lPart As Long
Dim ws As Worksheet
Dim something As Variant
Dim box As Object
Set ws = Worksheets("Sheet2")
With Worksheets(1).Range("A1:a500")
Set lRow = .Find(What:="", SearchOrder:=xlRows, SearchDirection:=xlNext, LookIn:=xlValues)
End With
'Set lRow = Range("A1")
' If VBA.IsEmpty(lRow.Value) Then
' MsgBox ("POOP!")
' Else
' Set box = lRow.End(xlDown)
' End If
'lRow = Worksheets("Sheet2").Range("A33:A37")
'ws.Cells.Find(What:="*", SearchOrder:=xlRows, (From tutorial, always returned lRow = Nothing)
' SearchDirection:=xlPrevious, LookIn:=xlValues).Row 1
lPart = Me.cboPart.ListIndex
'check for a part number
If Trim(Me.cboPart.Value) = "" Then
Me.cboPart.SetFocus
MsgBox "Please enter a part name or number"
Exit Sub
End If
'copy the data to the database
'use protect and unprotect lines,
' with your password
' if worksheet is protected
With ws
' .Unprotect Password:="password"
.Cells(lRow, 1).Value = Me.cboPart.Value
.Cells(lRow, 2).Value = Me.cboPart.List(lPart, 1)
.Cells(lRow, 3).Value = Me.cboNum.Value
' .Cells(lRow, 4).Value = Me.txtDate.Value
.Cells(lRow, 5).Value = Me.txtQty.Value
' .Protect Password:="password"
End With
'Combobox1.linkedcell=C4
'clear the data
Me.cboPart.Value = ""
Me.cboNum.Value = ""
Me.txtQty.Value = ""
Me.cboPart.SetFocus
End Sub
Private Sub cmdClose_Click()
Unload Me
End Sub
The goal is to be able to click the "Add part" button and add multiple files and have it output to the work order (I think the range for the parts is A33:A55 or something similar)
I ALSO would like to know if there is a way to make BOTH the part name AND part numbers dependent in the UserForm depending on which one you enter? Though that is a lower priority.
I'm still not 100% on what you are trying to do, and you may have some sections commented out that you may want to use (ie the combobox). Your 1row range is finding the next empty cell which I don't think you want to do. But as for how you would input the information into a range, you probably need to change your ws With statement:
1row = 35 'or whatever row number
For n =0 to CountOfItemsToAdd 'could also be done with a For Each statement
'You will also need another for statement here to go through your part list
With ws
1row = 1row + (n*3)
' .Unprotect Password:="password" [you only need this if using passwords]
.Cells(lRow, 1).Value = Me.cboPart.Value
.Cells(lRow+1, 1).Value = Me.cboPart.List(lPart, 1)
.Cells(lRow+2, 1).Value = Me.cboNum.Value
' .Cells(lRow, 4).Value = Me.txtDate.Value
.Cells(lRow+3, 1).Value = Me.txtQty.Value
' .Protect Password:="pasword"
But to awnser your specific question, you change the first value in the .Cells reference which is the row index, not the second number, which is the column index.
Related
I am working on a spreadsheet that utilizes user input to fill out a table. This data is entered into a table with numerous columns required. I have a command button that creates a new row and inserts all the data validation necessary for a new line item (below is an example.)
My problem revolves on a specific a column (blue circle) where other cells rely on based on a "yes" or "no" string. If the column has a "yes", the adjacent cells do something. If the column has a "no", the adjacent cells do something different.
As this table grows in rows, my column range I am focused on will change dynamically. I want the VBA code to run if the worksheet experiences a change event in that dynamic range utilizing the "Worksheet_Change(ByVal Target As Range) sub.
Right now, I am defining that dynamic range in my commandbutton_click sub because everytime i click the button, a new row is added thus I need the spreadsheet to be aware that my range has changed (see my code below).
Sub CommandButton1_Click()
Application.EnableEvents = False
Dim LastRowEntry As Long
Dim DeviceNo As Integer
'Dim RTUTable As Range
'Determine the last entry row & Copy
LastRowEntry = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
DeviceNo = Sheet1.Cells(Rows.Count, 1).End(xlUp)
Sheet1.Cells(Rows.Count, 1).End(xlUp).EntireRow.Copy
'Once the last row is determined, go to the next row to paste
Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormats
Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValidation
'Incase the above cell has Conditional Formatting, we set the color back to "white"
Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).EntireRow.Interior.ColorIndex = 0
Application.CutCopyMode = False
ActiveCell.Value = DeviceNo + 1
With RTUTable
RTUTable = Sheet1.Range(("G7"), Sheet1.Cells(LastRowEntry + 1, "G"))
End With
Application.EnableEvents = True
End Sub
Then, in a different sub I enter code that will "check" to see if that dynamic range has had a change in value with a "yes" or "no" answer. This is where I enter my defined dynamic range (see my code below).
Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
'This code checks to see if the Device is polled by RTU
If Not Intersect(Target, Range(RTUTable)) Is Nothing Then
If ActiveCell.Value = "NO" Then
"DO SOMETHING"
Else
"DO SOMETHING"
End If
End If
Application.EnableEvents = True
End Sub
Can someone help me out on the error message "Type mismatch" I am receiving? Am I entering the dynamic range correctly into the intersect code?
Thank you
****Update - More information for Clarification*****
I have added some information in the array I am evaluating. Below is a snapshot of my spreadsheet.
When I go into the Debug mode, I am viewing my "Locals table" and see I am successfully capturing my information in an array.
I need to run the intersect command with this array
This has been resolved. Below is the code I used to determine the dynamic range and then the code evaluates that range for a change.
Dim dyString As String
Dim dyRange As Range
Dim LastRowEntry_1 As Integer
Dim i As Integer
LastRowEntry_1 = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(-2, 0).row + 1
dyString = "G8:G" & LastRowEntry_1
Set dyRange = Range(dyString)
If Not Intersect(Target, dyRange) Is Nothing Then
For i = 1 To 6
If ActiveCell.Value = "NO" Then
Target.Offset(0, i).Interior.ColorIndex = 23
Target.Offset(0, i).Font.Color = vbWhite
Target.Offset(0, i).Value = "N/A"
Target.Offset(0, i).Locked = True
ElseIf ActiveCell.Value = "YES" And ActiveCell.Offset(0, i).Value = "N/A" Then
Target.Offset(0, i).Value = ""
Target.Offset(0, i).Interior.ColorIndex = 0
Target.Offset(0, i).Font.Color = vbBlack
Target.Offset(0, i).Locked = False
To summarize:
No matter what, my dynamic range will always begin at cell "G8"
After that, the range will change dynamically. Either grows or shortens depending on
the info. So my "LastRowEntry_1" determines where that last cell entry is. (Note: I
had to offset it because of some footer information on my spreadsheet)
I created a string where I could combine the range of the fixed cell to the dynamic
cell.
Then I set that string as a range.
Then based if the target range was intersected or not, I run a "For" loop to perform
my conditional formatting.
I'm trying to build a new VBA function for Excel. I've got a book of sheets with a front page that always loads first, on this page I've got a combo box that lists all the other sheets in the book and a nice extract button that will pull out the chosen sheet to a new book. (Thanks to those here who helped with that). Now I need a new function that will use the same combo box, but instead only extract a small subset of the chosen sheet.
Unfortunately, that subset isn't on the same rows for every sheet, nor is the number of rows the same (so one sheet, the subset might be 10 rows, on another it might be 12, on another it might be 20, etc etc etc).
On the plus side, there are merged rows (from column A to G) at the start and end of each subset - with specific text, which could be used to search for.
After some back and forth, I've got a better bit of code that I think is almost working:
Sub ZCPS_Extract()
Dim StartRow
Dim EndRow
Dim Zws As Worksheet
Dim wbkOriginal As Workbook
Set wbkOriginal = ActiveWorkbook
StartRow = 1
EndRow = 1
'sets site details into the header of the ZCPS checksheet
Worksheets(Sheet1.CmbSheet.Value).Range("B3").Value = Worksheets("front page").Range("E6")
Worksheets(Sheet1.CmbSheet.Value).Range("D3").Value = Worksheets("front page").Range("N6")
Worksheets(Sheet1.CmbSheet.Value).Range("F3").Value = Worksheets("front page").Range("K6")
Set Zws = Sheets(Sheet1.CmbSheet.Value)
'selects ZCPS block from select estate sheet
StartRow = (Zws.Cells.Find("**** ZCPS Installation").Row) + 1
EndRow = (Zws.Cells.Find("**** Aztec Hotfixes").Row) - 1
'copy above block and paste into Z-MISC starting at row 5
Worksheets(Sheet1.CmbSheet.Value).Range(Cells(StartRow, 1), Cells(EndRow, 7)).Copy Worksheets("Z-MISC").Range("A5")
With ActiveWorkbook.Sheets("Z-MISC")
.Copy
ActiveWorkbook.SaveAs _
"C:\temp\" _
& ActiveWorkbook.Sheets("Z-MISC").Cells(3, 2).Text _
& " ZCPS CheckSheet " _
& Format(Now(), "DD-MM-YY") _
& ".xlsm", _
xlOpenXMLWorkbookMacroEnabled, , , , False
End With
'code to close the original workbook to prevent accidental changes etc
Application.DisplayAlerts = False
wbkOriginal.Close
Application.DisplayAlerts = True
End Sub
It's error on the line for copying, I'm getting a runtime error of "Application-defined or object-defined error" which to my limited knowledge isn't helping me. Any assistance/pointers/suggestions are welcomed.
Sub ismerged()
Dim start As Integer, finish As Integer
For i = 1 To Range("A655").End(3).Row + 1
If Cells(i, "A").MergeCells = True Then
start = i
Exit For
End If
Next
For i = start To Range("A655").End(3).Row + 1
If Cells(i, "A").MergeCells = True Then
finish = i
End If
Next
MsgBox start
MsgBox finish
End Sub
Then I guess you can select your data as you wish.
I'm not sure about the way you reference your sheet. I will assume 'comboboxvalue' contains the name or the number of the sheet you are selecting. Your code should be something like the following.
Sub Z_Extract()
Dim StartRow
Dim EndRow
Dim ws As Worksheet
Set ws = Sheets(comboboxvalue)
StartRow = ws.Cells.Find("**** ZC").Row
EndRow = ws.Cells.Find("****").Row
'Im assuming you have values up to column G
ws.Range(ws.Cells(StartRow, 1), Cells(EndRow, 7)).Copy
'Now that you have the correct Range selected you can copy it to your new workbook
'SelectedRange.Copy Etc.....
'Cleanup
Set ws = Nothing
End Sub
Got it working.
Set Zws = Sheets(Sheet1.CmbSheet.Value)
'selects ZCPS block from selected estate sheet
StartRow = (Zws.Cells.Find("**** ZCPS Installation").Row)
EndRow = (Zws.Cells.Find("**** Aztec Hotfixes").Row) - 1
'copy above block and paste into Z-MISC starting at row 10
Sheets(Sheet1.CmbSheet.Value).Activate
ActiveSheet.Range(Cells(StartRow, 1), Cells(EndRow, 7)).Select
Selection.Copy
Sheets("Z-MISC").Select
Range("A10").Select
ActiveSheet.Paste
I'm new to this forum but have been building up my coding experience in the last couple of months due to the VBA requirements of my current role. Today's problem has seen me trawling through many sites (and my Excel VBA for Dummies book), but I haven't quite nailed it.
I am trying to make an audit tracker file in Excel for our company Risk Register. The idea is that once the risk register is established, any changes will create an audit trail (on a separate tab) which shows both the old and the new record.
I have written the code using the Change Event handler. I want my macro to fire every time there is a change and do the following:
1. Make a reference of the old cell value (what the user has just overwritten)
2. Jump to the 'Audit trail' tab and paste two copies of the full risk record - each risk record is a row of data that occupies 17 columns
3. In the first copy of these 17 columns, work out which column was edited and replace this cell with the old cell value (captured in step 1)
4. Insert a time stamp
5. Have conditional formatting highlight the record that has changed [this function is not required in the code as I've set it up within the spreadsheet itself]
6. Jump back to cell where the user just made their edit (on the 'Risk Register' tab)
I have managed steps 1, 2 and 4-7 but I am having problems getting the code to input the "old cell value" into the right spot in the 'Audit Tracker' tab. I can get it there if I manually define the cell range for it to paste into, but I can't seem to make it dynamic so that it will automatically recognize what field the user is changing and ensure the same field is amended in the audit trail.
Would really appreciate any insights as to why the "PasteRange.Value = Worksheets("Risk Register").Range("oldValuePaste")" line isn't working
My code is as follows:
Dim oldValue As Variant
Dim LastRow As Long
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.ScreenUpdating = False
If Not Intersect(Target, Range("b13:r13")) Is Nothing Then
oldValue = Target.Value
End If
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
If Not Intersect(Target, Range("b13:r14")) Is Nothing Then
If Target.Value <> oldValue Then
'MsgBox "You just changed " & Target.Address
Cells(65, 5).Value = oldValue 'this cell is a named range called: OldValuePaste
Cells(66, 5).Value = Target.row 'this cell is a named range called: OldValueRowNumber
Cells(67, 5).Value = Target.Column 'this cell is a named range called: OldValueColumnNumber
Range(Cells(Target.row, 2), Cells(Target.row, 18)).Copy
'Cells(70, 2).PasteSpecial xlPasteValues
Call Paste_on_AuditSheet
Sheets("Risk Register").Activate
Target.Select
Application.CutCopyMode = False
End If
End If
Application.ScreenUpdating = True
End Sub
_____________________________________________________________________________________________________
Sub Paste_on_AuditSheet()
Application.ScreenUpdating = False
Dim LastRow As Long
Dim ColNum As Long
Dim PasteRange As Range
ColNum = OldValueColumnNumber
Sheets("Audit trail").Select
'MsgBox "Activated " & ActiveSheet.Name
'Find the last used row in a Column: column B in this example
With ActiveSheet
LastRow = .Cells(.Rows.Count, "B").End(xlUp).row
End With
Set PasteRange = Cells(LastRow, ColNum)
'The following two lines bring in the new data and paste into old record and new record sections:
Cells(LastRow + 1, 2).PasteSpecial xlPasteValues
Cells(LastRow + 1, 20).PasteSpecial xlPasteValues
'Then this line goes back over the piece just pasted in and changes one cell in "old record" section to what it was prior to the edit:
'PasteRange.Value = Worksheets("Risk Register").Range("oldValuePaste")
'Above line of code is not working, but can get it to do the right thing using this code (although it's not dynamic):
Range("E3").Value = Worksheets("Risk Register").Range("oldValuePaste")
'Add a time stamp:
Cells(LastRow + 1, 1) = Now
Application.ScreenUpdating = True
End Sub
One last point - despite my repeated use of Application.ScreenUpdating commands, I still get some screen flashing - any ideas why?
Thanks in advance for the help!
In reviewing your code, I saw a few things that I didn't think would work as you supposed they would, and also recognized that your code could be made much simpler and just be called from the Worksheet_Change event.
So the refactored code below and let me know if you have issues:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("b13:r14")) Is Nothing Then
'get oldValue
Dim sNewVal As String, sOldVal As String
sNewValue = Target.Value 'store current or "new" value since this is what is stored after the cell change takes place
With Application
.EnableEvents = False 'turns off event firing so the code will not go into endless loop
.Undo 'undo the change (to store old value in next line)
End With
sOldValue = Target.Value 'store old value
Target.Value = sNewValue 'reset new value
Dim lCol As Long
lCol = Target.Column 'which column of data was changed
'assumes columns A-Q are 17 columns
Me.Range(Me.Cells(Target.Row, 1), Me.Cells(Target.Row, 17)).Copy
With Sheets("Audit Trail")
Dim lRow As Long
lRow = .Range("B" & .Rows.Count).End(xlUp).Offset(1).Row
.Range("B" & lRow).PasteSpecial xlPasteValues
.Range("B" & lRow + 1).PasteSpecial xlPasteValues
.Range("A" & lRow).Value = Now
.Cells(lRow, lCol + 1).Value = sOldValue 'store old value in first pasted line ... add 1 since starting from column B
End With
End If
Application.EnableEvents = True
End Sub
I have a workbook containing a list of all invoices from all branches, let's call it "Everything", and basically I need to search if the invoices are found in another file containing each branch's invoices,. It's actually on file for each branch, and each file is divided with sheets by month, and I need to check in every sheet and then insert a value in a cell. Let's call this one "0001" and so on for each branch.
The "everything" file contains basically one column with the branch number, one with the invoice number, one with the issuer code and one saying if it was found on the branches files. The branches files contains the same except the branch number, and the last column says if the invoice is on the "Everything" file or not. There are cases where an invoice is on the branch file and is not on the "everything file" and also cases where it is on the everything file and is not on the branches file.
What I tried to do was insert a loop in VBA so it would go automatically invoice after invoice in the everything file and open the specific branch file, then search for the invoice number in each sheet. I would also need to check if the issuer is the same, but first I tried this code and when it searched for the value it returned the wrong cell! Here is the code:
Dim sh As Worksheet
Dim iLoop As Integer
For iLoop = 7 To 1719
' this is where the invoices are in an excel sheet
iloopoffset = iLoop - 6
' as you see above, the list of invoices starts at line 7, so I used this to offset
If Range("K6").Offset(iloopoffset).Value = "No" Then
' Column K is the one saying if the invoice was found or not in the branches file
Set searchedvalue = Range("B6").Offset(iloopoffset, 0)
' I used this so i could use the value in the .find formula
MsgBox (searchedvalue.Value)
Workbooks.Open ("C:\Users\xxxxxx\Documents\xxxxxx\XML " + Range("D6").Offset(iloopoffset).Value)
For Each sh In Worksheets
If ActiveSheet.Name = "062015" Or "052015" Or "042015" Or "032015" Or "022015" Or "012015" Or "122014" Or "112014" Then
' I needed to do this because on the sheets with the names above, the searched value will be in another column. sheets before 112014 are different.
Set NFE = Worksheets(sh.Name).Range("B:B").Find(Range("B6").Offset(iloopoffset, 0).Value, lookat:=xlPart)
Else
Set NFE = Worksheets(sh.Name).Range("A:A").Find(Range("B6").Offset(iloopoffset, 0).Value, lookat:=xlPart)
End If
If Not NFE Is Nothing Then
MsgBox ("Found on sheet " + ActiveSheet.Name + " " + NFE.Address)
Range(NFE.Address).Offset(, 12).Value = "YES"
' yes for found
ActiveWorkbook.Save
ActiveWindow.Close
End If
Next sh
ActiveWorkbook.Save
ActiveWindow.Close
End If
Next iLoop
End Sub
What is going on? I am a true noob in VBA, but i didn't find anything wrong with this code... can you help me?
Untested:
Sub test()
Const FILE_ROOT As String = "C:\Users\xxxxxx\Documents\xxxxxx\XML "
Dim shtAll As Worksheet, rw As Range, searchedvalue
Dim sh As Worksheet, wb As Workbook
Dim iLoop As Long, colSrch As Long, NFE As Range
Dim arrSheets
Set shtAll = ActiveWorkbook.Sheets("Everything") 'adjust to suit...
'sheets to watch out for....
arrSheets = Array("062015", "052015", "042015", "032015", "022015", _
"012015", "122014", "112014")
For iLoop = 7 To 1719
Set rw = shtAll.Rows(iLoop)
'if not found...
If rw.Cells(1, "K").Value = "No" Then
searchedvalue = rw.Cells(1, "B").Value
Set wb = Workbooks.Open(FILE_ROOT & rw.Cells(1, "D").Value)
For Each sh In wb.Worksheets
'which column to search in? check if sheet name is in arrSheets
colSrch = IIf(IsError(Application.Match(sh.Name, arrSheets, 0)), 1, 2)
Set NFE = sh.Columns(colSrch).Find(searchedvalue, lookat:=xlPart)
If Not NFE Is Nothing Then
MsgBox ("Found on sheet " + ActiveSheet.Name + " " + NFE.Address)
NFE.Offset(, 12).Value = "YES"
wb.Save
Exit For
End If
Next sh
wb.Close savechanges:=False
End If
Next iLoop
End Sub
EDIT
If Not NFE Is Nothing And sh.Range(NFE).Offset(, 8) = cnpj Then
A couple of problem I see here:
NFE is already a Range, so you can just do NFE.Offset(,8)
VBA will always evaluate both parts of an And, even if the first part is False, so in cases where NFE is Nothing the second part will cause a run-time error (since you can't Offset from Nothing...). To handle this you need two distinct If blocks:
If Not NFE Is Nothing Then
If NFE.Offset(, 8) = cnpj Then
'do something
End If
End If
Should do it.
I'm very new to VBA, and I'm trying to move particular items within a column to another sheet for a report.
This is my Macro:
Sub DoIHaveaPRDesignation()
Dim rng As Range
Dim i, Lastrow
Dim splitValues() As String
Lastrow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Sheets("Sheet2").Range("A1:I500").ClearContents
Sheets("Sheet2").Cells(1, 1).Value = "Pair"
Sheets("Sheet2").Cells(1, 2).Value = "Commit"
Sheets("Sheet2").Cells(1, 3).Value = "CKID"
Sheets("Sheet2").Cells(1, 4).Value = "Status"
Sheets("Sheet2").Cells(1, 5).Value = "Terminal"
Sheets("Sheet2").Cells(1, 6).Value = "Address"
Set rng = ActiveCell
Dim moveValue As String
Do While rng.Value <> Empty
If InStr(rng.Value, " pr") = 0 Then
MsgBox "Haven't found Pair "
Else
MsgBox rng.Value
End If
Set rng = rng.Offset(1)
rng.Select
Loop
MsgBox "Done!"
End Sub
This is one instance of the data (Column A, Rows 1 - 6):
pr 1 stat RCT commit stat P
sys: type 73RMD no 1 slot: 1 lt: field stat DZ7K co stat NREQ
ckid NONE lp stat RCT 11-30-13 bp/clr 601 tea 1975 W SOUTHPORT RD
type FIXED tec IPLPINPL fld side capr 1975W:279
dist tea 7250 WINSLET BLVD type FIXED addr: 7250 WINSLET BLVD
UNIT 2D serv tea 7250 WINSLET BLVD type FIXED
The code finds the occurance of "pr", but I cannot seem to fidgure out how to pick it up and move it. I need to repeat this for the 6 columns I formatted on sheet 2, but if I get help with the first I can figure out the rest.
Thanks!
This answer discusses features of your existing code that are not recommended and introduces techniques that I believe are relevant to your requirement.
Issue 1
Dim i, Lastrow
The above declares i and Lastrow as variants which can hold anything. For example, the following code is valid:
i = "A"
i = 5
Variants can be very useful but they are slower to access than properly typed variables. I recommend:
Dim i As Long, Lastrow As Long
Issue 2
Sheets("Sheet2").Range("A1:I500").ClearContents
I assume Range("A1:I500") is intended to be larger than the area that was used on a previous run of the macro.
I would write Sheets("Sheet2").Cells.ClearContents and let Excel worry about the range used last time.
Note that ClearContents, as the name implies, only clears the contents. Clear will also clear any formatting. Sheets("Sheet2").Cells.EntireRow.Delete will delete contents and formatting and restore the column widths to their default. However, ClearContents may be adequate for your needs.
Issue 3
Sheets("Sheet2").Range("A1:I500").ClearContents
Sheets("Sheet2").Cells(1, 1).Value = "Pair"
Sheets("Sheet2").Cells(1, 2).Value = "Commit"
Sheets("Sheet2").Cells(1, 3).Value = "CKID"
Sheets("Sheet2").Cells(1, 4).Value = "Status"
Sheets("Sheet2").Cells(1, 5).Value = "Terminal"
Sheets("Sheet2").Cells(1, 6).Value = "Address"
Use of the With statement generally makes your code clearer and faster:
With Sheets("Sheet2")
.Range("A1:I500").ClearContents
.Cells(1, 1).Value = "Pair"
.Cells(1, 2).Value = "Commit"
With .Cells(1, 3)
.Value = "CKID"
.Interior.Color = RGB(0, 240, 240)
End With
.Cells(1, 4).Value = "Status"
.Cells(1, 5).Value = "Terminal"
.Cells(1, 6).Value = "Address"
End With
I have coloured cell C1 to show that With statements can be nested.
Issue 4
Set rng = ActiveCell
As I understand it, the source data is in worksheet Sheet1 and starts at cell A1. The above means your code will start at whatever cell in whatever worksheet the user has positioned the cursor. If there is a fixed starting point then set that in your code. If you do want the user to be able to control the starting point consider:
If ActiveCell.Worksheet.Name <> "Sheet1" Then
Call MsgBox("Please position the cursor to the desired starting " & _
"point in worksheet ""Sheet1""", vbOKOnly)
Exit Sub
End If
Issue 5
Set rng = ActiveCell
:
Set rng = rng.Offset(1)
rng.Select
Accessing a selected cell is much slower than accessing the cell using VBA addressing. I have also seen programmers get hopeless confused about the current location of the cursor when using Offset. You have used VBA addressing to set the header row and I have used it in my sample code below.
Issue 6
Lastrow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Do While rng.Value <> Empty
You set Lastrow to the number of the last row with a value but your loop moves down the column until it hits an empty cell. If there are no empty rows within the body of the data, this will give the same result. However I suggest you decide which approach is appropriate.
I would avoid the use of Empty. See What is the difference between =Empty and IsEmpty() in VBA (Excel)?.
Sample code
The following code includes the parts relevant to your question. I move the contents of cells containing " pr" to column 1 of worksheet "Sheet2" which is what you seem to be asking. However, if you wanted to split cells containing " pr" and copy selected parts to Sheet2, I would have handled your requirement in a different way. I can add a further section to this answer if you clarify what you seek.
Option Explicit
Sub MovePRRows()
Dim Rng As Range
Dim RowSheet1Crnt As Long
Dim RowSheet1Last As Long
Dim RowSheet2Crnt As Long
Dim WSht2 As Worksheet
Set WSht2 = Worksheets("Sheet2")
WSht2.Cells.EntireRow.Delete
RowSheet2Crnt = 2
With Worksheets("Sheet1")
RowSheet1Last = .Cells(Rows.Count, "A").End(xlUp).Row
For RowSheet1Crnt = 1 To RowSheet1Last
Set Rng = .Cells(RowSheet1Crnt, 1)
If Rng.Value <> "" Then
If InStr(1, Rng.Value, " pr") <> 0 Then
Rng.Copy Destination:=WSht2.Cells(RowSheet2Crnt, 1)
RowSheet2Crnt = RowSheet2Crnt + 1
End If
End If
Next
End With
End Sub