Tabulate test scores - vba

I am working on vba code and would like to do the following:
Read:
A B
1 John 100
2 Jill 90
3 John 95
4 Amy 82
Change to (in alphabetical order):
A B C
1 Amy 82
2 Jill 90
3 John 100 95
Ultimately i need it to display the student's name and all scores next to the name.
So far i have this:
Sub Combine()
Dim J As Integer
Dim wrk As Workbook 'Workbook object - Always good to work with object variables
Dim wrk1 As Worksheet
Dim r1, r2, r3, r4, r5, r6, r7, ra, rb, rc, rd, re, rf, rg As Range
Sheets("Sheet2").Select
Set r1 = Range("D:D")
Set r2 = Range("B:B")
Set r3 = Range("E:E")
Set r4 = Range("C:C")
Set r5 = Range("F:F")
Set r6 = Range("H:H")
Set r7 = Range("AX:AX")
Sheets("Sheet3").Select
Set ra = Range("D:D")
Set rb = Range("B:B")
Set rc = Range("E:E")
Set rd = Range("C:C")
Set re = Range("F:F")
Set rf = Range("H:H")
Set rg = Range("AX:AX")
Set wrk = Workbooks.Add
ActiveWorkbook.Sheets(2).Activate
r1.Copy Range("A1")
r2.Copy Range("B1")
r3.Copy Range("C1")
r4.Copy Range("D1")
r5.Copy Range("E1")
r6.Copy Range("F1")
r7.Copy Range("G1")
ActiveWorkbook.Sheets(3).Activate
ra.Copy Range("A1")
rb.Copy Range("B1")
rc.Copy Range("C1")
rd.Copy Range("D1")
re.Copy Range("E1")
rf.Copy Range("F1")
rg.Copy Range("G1")
On Error Resume Next
Sheets(1).Select
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A2").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A3").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Sheets(1).Select
Range("A1:AY100").Sort _
Key1:=Range("C1"), Key2:=Range("B1"), Header:=xlYes
Next
End Sub

I would create a pivot table for your case. It's easy to create, updates easily and good to maintain. However, here is some piece of code:
Sub pivotDataInColumns()
Dim sourceSheet As Excel.Worksheet
Dim destinationSheet As Excel.Worksheet
Dim sourceRow As Long
Dim destinationRow As Long
Dim matchRow As Long
Dim searchColumn As Excel.Range
Dim nameToFind As String
Dim lastColumn As Long
Application.ScreenUpdating = False
With ThisWorkbook
'Change Worksheet name to suit:
Set sourceSheet = ThisWorkbook.Worksheets("Sheet1")
Set destinationSheet = ThisWorkbook.Worksheets.Add
End With
Set searchColumn = destinationSheet.Columns("A")
For sourceRow = 1 To getLastRow(sourceSheet.Columns("A"))
nameToFind = sourceSheet.Cells(sourceRow, "A").Value
destinationRow = getMatchRow(nameToFind, searchColumn)
If destinationRow = 0 Then
destinationRow = getLastRow(destinationSheet.Columns("A")) + 1
destinationSheet.Cells(destinationRow, "A").Value = sourceSheet.Cells(sourceRow, "A").Value
End If
lastColumn = getLastColumn(destinationSheet.Rows(destinationRow)) + 1
destinationSheet.Cells(destinationRow, lastColumn).Value2 = sourceSheet.Cells(sourceRow, "B").Value2
Next sourceRow
'Remove row 1 garbage and sort:
With destinationSheet
.Rows(1).Delete
.UsedRange.Sort Key1:=.Range("A1"), _
Order1:=xlAscending, _
Header:=xlNo
End With
Application.ScreenUpdating = True
MsgBox "Data processed successfully.", vbInformation
End Sub
Private Function getMatchRow(searchValue As Variant, _
searchArray As Variant) As Long
'This function returns 0 if searchValue is not on searchArray.
Dim element As Long
On Error Resume Next
element = WorksheetFunction.Match(CDbl(searchValue), searchArray, 0)
If element = 0 Then element = WorksheetFunction.Match(CStr(searchValue), searchArray, 0)
getMatchRow = element
End Function
Private Function getLastRow(sourceRange As Excel.Range) As Long
Dim parentSheet As Excel.Worksheet
Dim lastRow As Long
Set parentSheet = sourceRange.Parent
With parentSheet
lastRow = .Cells(.Rows.Count, sourceRange.column).End(xlUp).row
End With
getLastRow = lastRow
End Function
Private Function getLastColumn(sourceRange As Excel.Range) As Long
Dim parentSheet As Excel.Worksheet
Dim lastColumn As Long
Set parentSheet = sourceRange.Parent
With parentSheet
lastColumn = .Cells(sourceRange.row, .Columns.Count).End(xlToLeft).column
End With
getLastColumn = lastColumn
End Function

Related

Search a each value from a column of sheet in another sheet's column and if find then paste entire row in output

I'm new to this so please help me. I have a workbook with below three sheets-
Sheet1- Has 3 cloumns- A,B,C
Sheet2- Has One Column- A
**Ouput
If Value in a cell of Sheet1- Column B matches with value in any cell of Sheet2 Column A then copy that entire row and paste to next available blank row (starts from column A) of output sheet.
column B of sheet 2 can have duplicate cells and all the matched cells should go to next available row of output sheet.
**Sheet 1** **Sheet 2** **Output**
A B C A 3 Glen 28
1 Jen 26 Glen 1 Jen 26
2 Ben 24 Jen 4 Jen 18
3 Glen 28
4 Jen 18
I tried below. Not sure how good it is-
Sub Test()
Set objwork1 = ActiveWorkbook ' Workbooks("Search WR")
Set obj1 = objwork1.Worksheets("Header")
Set obj2 = objwork1.Worksheets("XML1")
Set obj3 = objwork1.Worksheets("VC")
Set obj4 = objwork1.Worksheets("Output")
i = 2
j = 2
Do Until (obj3.Cells(j, 1)) = ""
If obj2.Cells(i, 2) = obj3.Cells(j, 1) Then
Set sourceColumn = obj2.Rows(i)
Set targetColumn = obj4.Rows(j)
sourceColumn.Copy Destination:=targetColumn
Else
i = i + 1
End If
j = j + 1
Loop
End Sub
Tried below as well-
Sub Check()
Set objwork1 = ActiveWorkbook ' Workbooks("Search WR")
Set obj1 = objwork1.Worksheets("Header")
Set obj2 = objwork1.Worksheets("XML1")
Set obj3 = objwork1.Worksheets("VC")
Set obj4 = objwork1.Worksheets("Output")
Dim LR As Long, i As Long, j As Long
j = 2
LR = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LR
For j = 2 To LR
obj3.Select
If obj3.Range("A" & i).value = obj2.Range("B" & j).value Then
Rows(j).Select
Selection.Copy
obj4.Select
obj4.Range("A1").End(xlDown).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
obj3.Select
End If
Next j
Next i
End Sub
Another approach
Copy all rows from Sheet1 to Output
Sort Output by custom list order (Sheet2)
Remove all rows in Output not in list (beginning in the last row)
So …
Option Explicit
Public Sub CopyListedRowsAndSortByListOrder()
Dim wsSrc As Worksheet
Set wsSrc = Worksheets("Sheet1")
Dim lRowSrc As Long
lRowSrc = wsSrc.Cells(wsSrc.Rows.Count, "A").End(xlUp).Row
Dim wsList As Worksheet
Set wsList = Worksheets("Sheet2")
Dim lRowList As Long
lRowList = wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row
Dim wsDest As Worksheet
Set wsDest = Worksheets("Output")
'Copy all rows
wsSrc.Range("A1:C" & lRowSrc).Copy wsDest.Range("A1")
Dim lRowDest As Long
lRowDest = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Row
'sort Output column B by list in Sheet2
With wsDest.Sort
.SortFields.Add Key:=wsDest.Range("B2:B" & lRowDest), _
SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
Join(WorksheetFunction.Transpose(wsList.Range("A2:A" & lRowList).Value), ","), DataOption:=xlSortNormal
.SetRange Range("A1:C" & lRowDest)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'remove all rows not in list (backwards)
Dim i As Long
For i = lRowDest To 2 Step -1
If Not IsError(Application.Match(wsDest.Cells(i, "B"), wsList.Range("A2:A" & lRowList))) Then Exit For
Next i
wsDest.Range(i + 1 & ":" & lRowDest).Delete xlShiftUp
End Sub
Something like (assumes you are copying from first sheet. That wasn't clear).
Option Explicit
Sub test()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set wb = ThisWorkbook
Set ws1 = wb.Worksheets("Sheet1")
Set ws2 = wb.Worksheets("Sheet2")
Set ws3 = wb.Worksheets("Output")
Dim currCell As Range, unionRng As Range
'Sheet1 column B matches sheet2 column A
With ws1
For Each currCell In Intersect(.Range("B:B"), .UsedRange)
If FoundInColumn(ws2, currCell, 1) Then
If Not unionRng Is Nothing Then
Set unionRng = Union(unionRng, currCell.EntireRow)
Else
Set unionRng = currCell.EntireRow
End If
End If
Next currCell
End With
If Not unionRng Is Nothing Then unionRng.Copy ws3.Range("A" & IIf(GetLastRow(ws3, 1) = 1, 1, GetLastRow(ws3, 1)))
End Sub
Public Function FoundInColumn(ByVal ws As Worksheet, ByVal findString As String, ByVal columnNo As Long) As Boolean
Dim foundCell As Range
Set foundCell = ws.Columns(columnNo).Find(What:=findString, After:=ws.Cells(1, columnNo), LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not foundCell Is Nothing Then FoundInColumn = True
End Function
Public Function GetLastRow(ByVal ws As Worksheet, Optional ByVal columnNumber As Long = 1) As Long
With ws
GetLastRow = .Cells(.Rows.Count, columnNumber).End(xlUp).Row
End With
End Function
If it is everything from sheet2 that matches to copy then:
Option Explicit
Sub test2()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set wb = ThisWorkbook
Set ws1 = wb.Worksheets("Sheet1")
Set ws2 = wb.Worksheets("Sheet2")
Set ws3 = wb.Worksheets("Output")
Dim currCell As Range, unionRng As Range
Dim dict As Dictionary 'tools > references > ms scripting runtime
Set dict = New Dictionary
'Sheet1 column B matches sheet2 column A
With ws1
For Each currCell In Intersect(.Range("B:B"), .UsedRange)
If Not dict.Exists(currCell.Value) And Not IsEmpty(currCell) Then
dict.Add currCell.Value, currCell.Value
Dim tempRng As Range
Set tempRng = GatherRanges(currCell.Value, Intersect(ws2.Range("A:A"), ws2.UsedRange))
If Not tempRng Is Nothing Then
If Not unionRng Is Nothing Then
Set unionRng = Union(unionRng, tempRng)
Else
Set unionRng = tempRng
End If
End If
End If
Next currCell
End With
If Not unionRng Is Nothing Then unionRng.EntireRow.Copy ws3.Range("A" & IIf(GetLastRow2(ws3, 1) = 1, 1, GetLastRow2(ws3, 1)))
End Sub
Public Function GatherRanges(ByVal findString As String, ByVal searchRng As Range) As Range
Dim foundCell As Range
Dim gatheredRange As Range
With searchRng
Set foundCell = searchRng.Find(findString)
Set gatheredRange = foundCell
Dim currMatch As Long
For currMatch = 1 To WorksheetFunction.CountIf(.Cells, findString)
Set foundCell = .Find(What:=findString, After:=foundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not gatheredRange Is Nothing Then
Set gatheredRange = Union(gatheredRange, foundCell)
Else
Set gatheredRange = foundCell
End If
Next currMatch
End With
Set GatherRanges = gatheredRange
End Function
Public Function GetLastRow2(ByVal ws As Worksheet, Optional ByVal columnNumber As Long = 1) As Long
With ws
GetLastRow2 = .Cells(.Rows.Count, columnNumber).End(xlUp).Row
End With
End Function
you could try this
Sub Test()
Dim filts As Variant
With Worksheets("Sheet2")
filts = Application.Transpose(.Range("A2", .Cells(.Rows.Count, 1).End(xlUp)).Value)
End With
With Worksheets("Sheet1").Range("A1").CurrentRegion
.AutoFilter Field:=2, Criteria1:=filts, Operator:=xlFilterValues
If Application.WorksheetFunction.Subtotal(103, .Columns(1)) > 1 Then .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0).SpecialCells(xlCellTypeVisible).Copy Worksheets("Output").Range("A1")
.Parent.AutoFilterMode = False
End With
End Sub

VBA EXCEL !can any one help me in how to add an additional workbook in searching range in below code ,

can any one help me in how to add an additional workbook in searching range in below code ,
I want to search for a string inserted in "TextBox1" within a range (A2,G2000) of data located in Workbook "officerA" Worksheet "DATA", and then paste results found into Workbook "Mainwb" sheet "MAIN SCREEN" Range (A5,G500)
I am totally new to VBA and wrote this code quoting from many sources all your support is appreciated
Below is the code used to search within same workbook:
Private Sub CommandButton1_Click()
Dim wb1 As Workbook, Wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim strSearch As String
Dim f As Variant
Dim fAddress As String
Dim fRow As Long
Dim cellA As Variant
Dim cellB As Variant
Set Wb2 = Workbooks.Open("C:\Users\elhayani\Desktop\development\AML db\OfficerA.xlsx")
Set wb1 = Workbooks.Open("C:\Users\elhayani\Desktop\development\AML db\Mainwb.xlsm")
Set wb1 = ActiveWorkbook
Set ws2 = wb1.Sheets("MAIN SCREEN").Range("A5:G2000")
Set ws1 = Wb2.Worksheets("DATA")
strSearch = TextBox1.Value
ws1.Range("A5:G2000").ClearContents
Set dmr = Workbooks.Open("C:\Users\aselhayani\Desktop\Excel Reports\OfficerA.xlsx")
Set dmr = Worksheets("DATA")
strSearch = InputBox("Please enter T24 ID:", "Search Value")
pasteRowIndex = 5
If strSearch = vbNullString Then
MsgBox ("User canceled, or did not enter a value.")
Exit Sub
End If
With ws1.Range("A2:G2000")
Set f = .Find(strSearch, LookIn:=xlValues)
If Not f Is Nothing Then
fAddress = f.Address
Do
fRow = f.Row
cellA = ws2.Cells(fRow, 1).Value
cellB = ws2.Cells(fRow, 2).Value
cellC = ws2.Cells(fRow, 3).Value
cellD = ws2.Cells(fRow, 4).Value
cellE = ws2.Cells(fRow, 5).Value
cellF = ws2.Cells(fRow, 6).Value
cellG = ws2.Cells(fRow, 7).Value
ws1.Cells(pasteRowIndex, 1) = cellA
ws1.Cells(pasteRowIndex, 2) = cellB
ws1.Cells(pasteRowIndex, 3) = cellC
ws1.Cells(pasteRowIndex, 4) = cellD
ws1.Cells(pasteRowIndex, 5) = cellE
ws1.Cells(pasteRowIndex, 6) = cellF
ws1.Cells(pasteRowIndex, 7) = cellG
pasteRowIndex = pasteRowIndex + 1
Set f = .FindNext(f)
Loop While Not f Is Nothing And f.Address <> fAddress
End If
End With
MsgBox "Search Done"
End Sub
You should pass the worksheet in the external workbook as a parameter into another sub routine for processing.
Option Explicit
Private Sub CommandButton1_Click()
Const OfficerAPath = "C:\Users\best buy\Downloads\stackoverfow\temp\OfficerA.xlsx"
Const OfficerBPath = "C:\Users\best buy\Downloads\stackoverfow\temp\OfficerB.xlsx"
Dim wb As Workbook
Dim strSearch As String
strSearch = TextBox1.Value
If strSearch = vbNullString Then
MsgBox ("User canceled, or did not enter a value.")
Exit Sub
End If
Worksheets("MAIN SCREEN").Range("A5:G2000").ClearContents
' Process Workbooks OfficerAPath
Set wb = Workbooks.Open(OfficerAPath)
SearchWorksheet wb.Worksheets("DATA"), strSearch
wb.Close False
' Process Workbooks OfficerAPath
Set wb = Workbooks.Open(OfficerBPath)
SearchWorksheet wb.Worksheets("DATA"), strSearch
wb.Close False
MsgBox "Search Done"
End Sub
Sub SearchWorksheet(dmr As Worksheet, strSearch As String)
Dim f As Range, SearchRange As Range
Dim fAddress As String
Dim pasteRowIndex As Long, y As Integer
With dmr
Set SearchRange = .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
End With
With ThisWorkbook.Sheets("MAIN SCREEN")
pasteRowIndex = .Range("A" & Rows.Count).End(xlUp).Row
If pasteRowIndex < 5 Then pasteRowIndex = 5
Set f = SearchRange.Find(strSearch, LookIn:=xlValues)
If Not f Is Nothing Then
fAddress = f.Address
Do
For y = 1 To 7
.Cells(pasteRowIndex, y) = dmr.Cells(f.Row, y).Value
Next
.Cells(pasteRowIndex, 8) = dmr.Parent.Name
pasteRowIndex = pasteRowIndex + 1
Set f = SearchRange.FindNext(f)
Loop While Not f Is Nothing And f.Address <> fAddress
End If
End With
End Sub

Close and Re-open workbook followed by SaveAs .prn

I have been busy with creating a code for sorting a database in a new workbook.
Sheet2 of this workbook needs to be saved next to the workbook as "Sheet2.prn". I managed to do this, but today I needed to add 2 columns to Sheet2 and now for some reason the last step of resaving the file as .prn doesn't work anymore. I really don't have a clue what I have done wrong as I'm pretty sure I didn't change anything to the last part of my code.
This is my code:
Option Explicit
Sub RowCount()
Dim Oldstatusbar As Boolean
Dim DOF As Integer, Counter As Integer
Dim CurrentMin As Long, StartRow As Long, StartColumn As Long
Dim OutputColumn As Long, OutputRow As Long, InputValue As Long
Dim Borehole As String, Start_Row As String, End_Row As String, Output As String, FolderPath As String
Dim CurrentName As String
Dim rng As RANGE, Cell As RANGE, brh As RANGE, Undef1 As RANGE, Undef2 As RANGE
Dim r1 As RANGE, r2 As RANGE, r3 As RANGE, r4 As RANGE, r5 As RANGE, r6 As RANGE, r7 As RANGE, r8 As RANGE, r9 As RANGE
Dim r10 As RANGE, r11 As RANGE, r12 As RANGE, r13 As RANGE
Dim wbMain As Workbook, wbWellsRowCount As Workbook
Dim wsLog As Worksheet, wsSheet1 As Worksheet, wsSheet2 As Worksheet
Dim HCdatabase2 As Variant
Oldstatusbar = Application.DisplayStatusBar
Set wbMain = Workbooks("HCdatabase2.xlsm")
Set wsLog = wbMain.Sheets("Log")
FolderPath = ThisWorkbook.Path
DOF = 1
Counter = 1
wsLog.Select
StartColumn = 1
StartRow = 1
wsLog.Cells(StartRow + DOF, StartColumn).End(xlDown).Select
Set rng = wsLog.RANGE(wsLog.Cells(StartRow + DOF, StartColumn), wsLog.Cells(StartRow + DOF, StartColumn).End(xlDown))
CurrentName = wsLog.Cells(StartRow + DOF, StartColumn).Value
CurrentMin = Cells(StartRow + DOF, StartColumn).Row
Set wbWellsRowCount = Workbooks.Add
wbWellsRowCount.SaveAs FolderPath & "\wbWellsRowCount.xls"
Set wsSheet1 = wbWellsRowCount.Sheets("Sheet1")
wsSheet1.Select
OutputColumn = 1
OutputRow = DOF + 1
wsSheet1.Cells(OutputRow, OutputColumn).Value = CurrentName
wsSheet1.Cells(OutputRow, OutputColumn + 1).Value = CurrentMin
wsSheet1.Cells(1, 1).Name = "Borehole"
wsSheet1.Cells(1, 2).Name = "Start_Row"
wsSheet1.Cells(1, 3).Name = "End_Row"
wsSheet1.Cells(1, 4).Name = "Output"
ActiveWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
Set wsSheet2 = wbWellsRowCount.Sheets("Sheet2")
Set r1 = Workbooks("HCdatabase2.xlsm").Worksheets("Log").RANGE("A:A")
Set r2 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").RANGE("A:A")
Set r3 = Workbooks("HCdatabase2.xlsm").Worksheets("Log").RANGE("J:J")
Set r4 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").RANGE("B:B")
Set r5 = Workbooks("HCdatabase2.xlsm").Worksheets("Log").RANGE("M:M")
Set r6 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").RANGE("C:C")
Set r7 = Workbooks("HCdatabase2.xlsm").Worksheets("Log").RANGE("AC:AC")
Set r8 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").RANGE("D:D")
Set r9 = Workbooks("HCdatabase2.xlsm").Worksheets("Log").RANGE("AF:AF")
Set r10 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").RANGE("E:E")
Set r11 = Workbooks("HCdatabase2.xlsm").Worksheets("Log").RANGE("D:D")
Set r12 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").RANGE("F:F")
Set r13 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").RANGE("G:G")
r1.Copy r2
r3.Copy r4
r5.Copy
r6.PasteSpecial Paste:=xlPasteValues
r7.Copy r8
r9.Copy
r10.PasteSpecial Paste:=xlPasteValues
r11.Copy r12
r11.Copy r13
Application.CutCopyMode = False
With wbWellsRowCount.Sheets("Sheet2")
With .RANGE("A2", .Cells(.Rows.Count, 1).End(xlUp))
.Offset(.Rows.Count).Value = .Value
.Offset(.Rows.Count, 1).Value = .Offset(, 3).Value
.Offset(.Rows.Count, 4).Value = .Offset(, 4).Value
.Offset(.Rows.Count, 5).Value = .Offset(, 5).Value
.Offset(.Rows.Count, 6).Value = .Offset(, 6).Value
.Offset(, 4).ClearContents
.Offset(, 3).EntireColumn.Delete
With .Offset(, 1).Resize(2 * .Rows.Count)
If WorksheetFunction.CountBlank(.Cells) > 0 Then .SpecialCells(XlCellType.xlCellTypeBlanks).EntireRow.Delete
End With
End With
With .RANGE("A2", .Cells(.Rows.Count, 1).End(xlUp)).Resize(, 7)
.Sort key1:=.Cells(1, 1), order1:=xlAscending, key2:=.Cells(1, 2), order2:=xlAscending, Header:=xlNo, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, DataOption2:=xlSortNormal
End With
End With
Set Undef1 = Workbooks("wbWellsRowCount.xls").Worksheets("Sheet2").UsedRange
On Error Resume Next
InputValue = -999
For Each Cell In Undef1
If IsEmpty(Cell) Then
Cell.Value = InputValue
End If
Next
On Error Resume Next
For Each Cell In r12
If (Cell) Then
Cell.Value = Left(Cell.Value, 2)
End If
Next
Columns("A:F").HorizontalAlignment = xlRight
Columns("A:F").AutoFit
Columns("E").ColumnWidth = 9
For Each Cell In rng
If Cell.Value <> CurrentName Then
wsSheet1.Cells(OutputRow, OutputColumn + 2).Value = Cell.Row - 1
CurrentName = Cell.Value
CurrentMin = Cell.Row
OutputRow = OutputRow + 1
wsSheet1.Cells(OutputRow, OutputColumn).Value = CurrentName
wsSheet1.Cells(OutputRow, OutputColumn + 1).Value = CurrentMin
wsSheet1.Cells(Counter + DOF, "D").Value = Counter
Counter = Counter + 1
End If
Next Cell
Set Cell = rng.End(xlDown)
wsSheet1.Cells(OutputRow, OutputColumn + 2).Value = Cell.Row
wsSheet1.Cells(Counter + DOF, "D").Value = Counter
wbWellsRowCount.Close True
wbWellsRowCount.Open
'wbWellsRowCount.Open FolderPath & "\wbWellsRowCount.xls"
wbWellsRowCount.Worksheets("Sheet2").SaveAs Filename:="HCShowDatabase.prn", FileFormat:=xlTextPrinter
Workbooks("HCShowDatabase.prn").Close True
wbMain.Activate
RANGE("A1").Select
ActiveWindow.ScrollRow = RANGE("A1").Row
Application.ScreenUpdating = True
Application.DisplayStatusBar = Oldstatusbar
End Sub
I tried both 2nd (worked fine before) and 3rd rule, but for some reason the file doesn't re-open.
To be specific, I want the workbook "wbWellsRowCount" to be saved and then re-opened so that I can SaveAs as Space delimited text file.
Can anyone help me with this?
Because the workbook is already open. It doesn't make any sense to close it and re-open it, doing so is expensive/time-consuming and serves no real purpose that I can see.
Also, you can't do it this way, because once you do the .Close True, the object is no longer available for you to use the .Open method, and were it not for your On Error Resume Next, this line would definitely raise an error (91: Object Variable Or With Block Not Set).
Get rid of:
wbWellsRowCount.Close True '### DELETE THIS LINE
wbWellsRowCount.Open '### DELETE THIS LINE
So that you're left with just this:
wbWellsRowCount.Worksheets("Sheet2").SaveAs Filename:="HCShowDatabase.prn", FileFormat:=xlTextPrinter
Workbooks("HCShowDatabase.prn").Close True

speed up the processing of excel vba

I've created excel vba file. However, it takes very long time to run the whole file because the total of the rows is up to 270,000 lines. Does anyone know how can I speed up the running process? Any help would be much appreciated. Thanks in advance.
Sub datemodifiedFile()
Dim File1 As Object
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set File1 = fso.getfile("C:\Users\Meg\Desktop\Master File.xlsx")
If Sheets("today").Range("B1").Value = File1.DateLastModified Then
Else
Sheets("today").Range("B1").Value = File1.DateLastModified
Dim WbB As Workbook
Set WbB = Workbooks.Open(Filename:="C:\Users\Meg\Desktop\Master File.xlsx", ReadOnly:=True)
Dim SheetB As Worksheet
Dim lastrow As Long
Set SheetB = WbB.Sheets("Sheet1")
SheetB.Select
Rows("1:1").Select
'Selection.AutoFilter
'ActiveSheet.Range("A:V").AutoFilter Field:=20, Criteria1:=""
Columns("A:V").Select
Selection.Copy
ThisWorkbook.Activate
Sheets("today").Select
Range("C1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Columns("A:X").Select
'ActiveSheet.Range("$A$1:$X$750001").RemoveDuplicates Columns:=Array(3, 4, 6), _
Header:=xlYes
Application.CutCopyMode = False
lastrow = Sheets("today").Range("D" & Rows.Count).End(xlUp).Row
Sheets("today").Cells(lastrow, 3).EntireRow.Delete
WbB.Close False
End If
End Sub
Sub dltnew()
Dim i As Long
Dim lrow As Long
lrow = Sheets("today").Range("C" & Rows.Count).End(xlUp).Row
For i = 2 To lrow
If Sheets("today").Cells(i, 2).Value = "NEW" Then
Sheets("today").Cells(i, 2).Value = ""
Sheets("today").Cells(i, 1).Value = ""
End If
Next i
End Sub
Sub comdate()
Dim Sheet1 As Worksheet
Dim Sheet3 As Worksheet
Dim lrow As Long
Dim i As Long
Set Sheet1 = ThisWorkbook.Sheets("main")
Set Sheet3 = ThisWorkbook.Sheets("today")
Sheet3.Range("A1").Value = Date
Sheet3.Range("A1").NumberFormat = "dd/mm/yyyy"
Sheet3.Range("A1").Font.Color = Sheet3.Range("A1").Interior.Color
Sheet3.Columns("A:A").EntireColumn.Hidden = False
If Sheet1.Range("B1").Value <> Sheet3.Range("A1").Value Then
Sheet1.Range("B1").Value = Sheet3.Range("A1").Value
lrow = Sheet1.Range("C" & Rows.Count).End(xlUp).Row
For i = 2 To lrow
If Sheet1.Cells(i, 2).Value = "NEW" Then
Sheet1.Cells(i, 2).Value = ""
End If
Next i
End If
End Sub
Sub Con()
Dim LasRow As Long
Application.ScreenUpdating = False
LasRow = Sheets("today").Range("C" & Rows.Count).End(xlUp).Row
Sheets("today").Range("A2:A" & LasRow).Formula = "=C2&G2&I2"
ActiveSheet.AutoFilterMode = False
Application.ScreenUpdating = True
End Sub
Sub Compare()
Dim mrow As Range, trow As Long
With Worksheets("main")
Set mrow = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
End With
trow = Worksheets("today").Range("A" & Rows.Count).End(xlUp).Row
With Worksheets("today")
For j = 2 To trow
If mrow.Find(What:=.Range("A" & j).Value, LookIn:=xlValues, LookAt:=xlWhole) Is Nothing _
Then .Range("B" & j).Value = "NEW"
Next j
End With
End Sub
Sub getnew()
Dim Sheet1 As Worksheet
Dim Sheet3 As Worksheet
Dim lastrow As Long
Dim i As Long
Dim erow As Long
Set Sheet1 = ThisWorkbook.Sheets("main")
Set Sheet3 = ThisWorkbook.Sheets("today")
lastrow = Sheet3.Range("C" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Sheet3.Cells(i, 2).Value = "NEW" Then
erow = Sheet1.Range("C" & Rows.Count).End(xlUp).Row + 1
Sheet3.Cells(i, 2).EntireRow.Copy Destination:=Sheet1.Range("A" & erow)
Application.CutCopyMode = False
Sheet1.Select
Range("A1:X750001").Select
Selection.Sort Key1:=Range("G2"), Order1:=xlAscending, Key2:=Range("C2") _
, Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom
End If
Next i
End Sub
Sub hidecellvalue()
Dim Sheet1 As Worksheet
Dim lastrow As Long
Dim k As Long
Set Sheet1 = ThisWorkbook.Sheets("main")
lastrow = Sheet1.Range("B" & Rows.Count).End(xlUp).Row
For k = 2 To lastrow
If Sheet1.Cells(k, 1).Value <> "NEW" Then
Sheet1.Cells(k, 1).Font.Color = Sheet1.Cells(k, 1).Interior.Color
'Sheet1.Columns("A:A").EntireColumn.Hidden = False
End If
Next k
End Sub
Sub hideSh1column()
Dim Sheet1 As Worksheet
Set Sheet1 = ThisWorkbook.Sheets("main")
Sheet1.Columns("A:A").EntireColumn.Hidden = True
Sheet1.Columns("D:F").EntireColumn.Hidden = True
Sheet1.Columns("H:H").EntireColumn.Hidden = True
Sheet1.Columns("L:L").EntireColumn.Hidden = True
Sheet1.Columns("N:N").EntireColumn.Hidden = True
Sheet1.Columns("P:P").EntireColumn.Hidden = True
End Sub
Sub HideSheet3()
Sheets("today").Visible = xlSheetVisible
End Sub
I would start with remove as much as .activate and select you have in your code and replace it with proper sheet.cell/range selection.
Then i would add this on beggining of your code
Dim previousScreenUpdating As Boolean
previousScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False
Dim previousCalculation As XlCalculation
previousCalculation = Application.Calculation
Application.Calculation = xlCalculationManual
and this on the end of your code
Application.ScreenUpdating = previousScreenUpdating
Application.Calculation = previousCalculation
This should be much faster.
You should always try to do as much using arrays as possible, rather than going through your data cell-by-cell.
In addition, a dictionary-based lookup is always going to beat using Find() when you're checking things in a large loop.
Sub Compare()
Dim mrow As Range, trow As Long, arr, r As Long
Dim d As Object, rngV As Range
Dim arrV, arrN, wsT As Worksheet, wsM As Worksheet
Set d = CreateObject("Scripting.Dictionary")
Set wsM = Worksheets("Main")
Set wsT = Worksheets("today")
'get all unique values in ColA on Main
arr = wsM.Range(wsM.Range("A2"), wsM.Cells(wsM.Rows.Count, 1).End(xlUp)).Value
For r = 1 To UBound(arr, 1)
d(arr(r, 1)) = 1
Next r
Set rngV = wsT.Range(wsT.Range("A2"), wsT.Cells(wsT.Rows.Count, 1).End(xlUp))
arrV = rngV.Value 'values from colA as array
arrN = rngV.Offset(0, 1).Value 'values from colB as array
'check colA against the dictionary and update colB array as needed
For r = 1 To UBound(arrV, 1)
If Not d.exists(arrV(r, 1)) Then arrN(r, 1) = "NEW"
Next r
'repopulate ColB with updated data
rngV.Offset(0, 1).Value = arrN
End Sub

Remove duplicated values in column, leaving only those which are higher in terms of rows

There is a sheet scr where column P has the following view:
P1=100
P2=100
P3=100
P4=100
P4=101
P5=101
P6=102
P7=102
P8=102
, meaning there are blocks of unique values. I need to leave only the upper value (here - P1, P4, P6). The other duplicated values should be erased. Therefore, I made the code below, but it does not work and gives no error.
Sub Test()
Dim wb1 As Workbook
Set wb1 = ActiveWorkbook
Set src = wb1.Sheets("Modules_List")
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim i As Long
Dim k As Integer
With src
For i = 1 To 100
For k = 1 To 100
If .Cells(i, "P").Value = .Cells(i + k, "P").Value Then .Cells(i + k, "P").Value = ""
Next k
Next i
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Here is your entire code over you last three questions.
Sub Copy_Data_by_Criteria()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim src As Worksheet
Dim Dst As Worksheet
Dim src2 As Worksheet
Set wb1 = ActiveWorkbook
Set wb2 = Workbooks.Open(Filename:="C:\Test.xlsx")
Set src = wb1.Sheets("Sheet1")
Set Dst = wb2.Sheets("Sheet1")
Set src2 = wb1.Sheets("Base 1")
Dim LastRow As Long
Dim r As Range
Dim CopyRange As Range
Dim Crit As Range
Dim strValue As Variant
LastRow = src.Cells(src.Rows.Count, "P").End(xlUp).Row
For Each Crit In src2.Range("G10:G" & 30)
If Crit <> "" Then
For Each r In src.Range("P6:P" & LastRow)
If r <> 0 Then strValue = r
If strValue = Crit Then
If CopyRange Is Nothing Then
Set CopyRange = r.EntireRow
Else
Set CopyRange = Union(CopyRange, r.EntireRow)
End If
End If
Next r
End If
Next Crit
If Not CopyRange Is Nothing Then
CopyRange.Copy Dst.Range("A1")
End If
End Sub
As to why your current code did not do what you wanted, Since you looped down to add the values you need to loop up to remove them:
Sub Test()
Dim wb1 As Workbook
Set wb1 = ActiveWorkbook
Set src = wb1.Sheets("Modules_List")
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim i As Long
Dim k As Integer
With src
For i = 100 To 1
If .Cells(i, "P").Value = .Cells(i - 1, "P").Value Then .Cells(i, "P").Value = ""
Next i
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub