This script is giving me an error because it consumes too much resources. What can I do to fix that?
Dim oSht As Worksheet
Dim i As Long, j As Integer
Dim LRow As Long, LCol As Long
Dim Email1Col As Integer, Email2Col As Integer, Email3Col As Integer
Dim arr As Variant
Dim SplEmail3 As String
'Definitions
Set oSht = ActiveSheet
Email1Col = 6
Email2Col = 7
Email3Col = 8
'-----------
With oSht
'LRow = .Range("G" & .Rows.Count).End(xlUp).Row
LRow = 1048576
'LCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
For i = 2 To LRow
'If oSht.Rows(i + 1).EntireRow = 0 Then GoTo Skip
If Cells(i, Email1Col).Value <> "" Or Cells(i, Email3Col).Value <> "" Then
If Cells(i, Email2Col) <> "" Then
'email2 to new row + copy other data
Rows(i + 1).EntireRow.Insert
oSht.Rows(i + 1).EntireRow.Value = oSht.Rows(i).EntireRow.Value
Range(Cells(i + 1, Email1Col), Cells(i + 1, Email3Col)).ClearContents
Cells(i + 1, Email1Col) = Cells(i, Email2Col)
'email3 to new row + copy other data
End If
If Cells(i, Email3Col) <> "" Then
arr = Split(Cells(i, Email3Col), ",", , 1)
For j = 0 To UBound(arr)
'split into single emails
SplEmail3 = Replace((arr(j)), " ", "", 1, , 1)
'repeat the process for every split
Rows(i + 2 + j).EntireRow.Insert
oSht.Rows(i + 2 + j).EntireRow.Value = oSht.Rows(i).EntireRow.Value
Range(Cells(i + 2 + j, Email1Col), Cells(i + 2 + j, Email3Col)).ClearContents
Cells(i + 2 + j, Email1Col) = SplEmail3
Next j
End If
Range(Cells(i, Email2Col), Cells(i, Email3Col)).ClearContents
Else
Rows(i).EntireRow.Delete
End If
Skip:
Next i
sample data:
col1, col2,..., col6, col7 , col8
name, bla, ...,mail1,mail2,(mail3,mail4,mail5)
needs to become this:
col1, col2,..., col6
name, bla, ...,mail1
Note: I have tested this with very small piece of data.. Give it a try and if you are stuck then let me know. We will take it from there.
Let's say our data looks like this
Now we run this code
Sub Sample()
Dim oSht As Worksheet
Dim arr As Variant, FinalArr() As String
Dim i As Long, j As Long, k As Long, LRow As Long
Set oSht = ActiveSheet
With oSht
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
arr = .Range("A2:H" & LRow).Value
i = Application.WorksheetFunction.CountA(.Range("G:H"))
'~~> Defining the final output array
ReDim Preserve FinalArr(1 To (LRow + i - 3), 1 To 6)
k = 0
For i = LBound(arr) To UBound(arr)
k = k + 1
FinalArr(k, 1) = arr(i, 1)
FinalArr(k, 2) = arr(i, 2)
FinalArr(k, 3) = arr(i, 3)
FinalArr(k, 4) = arr(i, 4)
FinalArr(k, 5) = arr(i, 5)
If arr(i, 6) <> "" Then FinalArr(k, 6) = arr(i, 6)
For j = 7 To 8
If arr(i, j) <> "" Then
k = k + 1
FinalArr(k, 1) = arr(i, 1)
FinalArr(k, 2) = arr(i, 2)
FinalArr(k, 3) = arr(i, 3)
FinalArr(k, 4) = arr(i, 4)
FinalArr(k, 5) = arr(i, 5)
FinalArr(k, 6) = arr(i, j)
End If
Next j
Next i
.Rows("2:" & .Rows.Count).Clear
.Range("A2").Resize(UBound(FinalArr), 6).Value = FinalArr
End With
End Sub
Output
You can use Power Query. Your comment led me to do some testing, and that can be done while recording a macro. For example, assuming your data is in a "table":
Sub createPQ()
ActiveWorkbook.Queries.Add Name:="Table1", Formula:= _
"let" & Chr(13) & "" & Chr(10) & " Source = Excel.CurrentWorkbook(){[Name=""Table1""]}[Content]," & Chr(13) & "" & Chr(10) & " #""Changed Type"" = Table.TransformColumnTypes(Source,{{""FirstName"", type text}, {""LastName"", type text}, {""blah1"", type text}, {""b lah2"", type text}, {""bla3"", type text}, {""email1"", type text}, {""email2"", type text}, {""email3"", type text}})," & Chr(13) & "" & Chr(10) & " #""Unpivoted Columns"" = Tab" & _
"le.UnpivotOtherColumns(#""Changed Type"", {""FirstName"", ""LastName"", ""blah1"", ""b lah2"", ""bla3""}, ""Attribute"", ""Value"")" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " #""Unpivoted Columns"""
Sheets.Add After:=ActiveSheet
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=Table1" _
, Destination:=Range("$A$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array("SELECT * FROM [Table1]")
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = False
.ListObject.DisplayName = "Table1_2"
.Refresh BackgroundQuery:=False
End With
End Sub
If your user adds data, and needs to refresh the query, Data Ribbon ► Connection tab ► Refresh (or you could create a button to do that if you prefer).
The unknown is how it will work on a DB of your size.
-- Before
-- After
Related
I want to make a dropdown that only contains 5/10 sheets that when i click on the sheet from the dropdown it proceeds to the sheet. At the moment I have a dropdown with all the sheets in it although I don't want them all.
Hopefully someone understands. Please feel free to ask for more information.
Thanks
This needs to be pasted on the sheet where the cell will change (not in a module). Be sure to swap "Sheet5" and "A2" in the code to the sheet name and cell range on your excel.
Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, ThisWorkbook.Sheets("Sheet5").Range("A2")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Stopsub:
Call ChangeSheet
Stopsub:
Application.EnableEvents = True
End Sub
Sub ChangeSheet()
Dim SelectedSheet As String
SelectedSheet = ThisWorkbook.Sheets("Sheet5").Range("A2")
ThisWorkbook.Sheets(SelectedSheet).Activate
End Sub
This is a slightly different concept, which uses hyperlinks to navigate through a workbook. Hope it helps you out.
Sub BuildTOC_A3()
Cells(3, 1).Select
BuildTOC
End Sub
Sub BuildTOC()
'listed from active cell down 7-cols -- DMcRitchie 1999-08-14 2000-09-05
Dim iSheet As Long, iBefore As Long
Dim sSheetName As String, sActiveCell As String
Dim cRow As Long, cCol As Long, cSht As Long
Dim lastcell
Dim qSht As String
Dim mg As String
Dim rg As Range
Dim CRLF As String
Dim Reply As Variant
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
cRow = ActiveCell.Row
cCol = ActiveCell.Column
sSheetName = UCase(ActiveSheet.Name)
sActiveCell = UCase(ActiveCell.Value)
mg = ""
CRLF = Chr(10) 'Actually just CR
Set rg = Range(Cells(cRow, cCol), Cells(cRow - 1 + ActiveWorkbook.Sheets.Count, cCol + 7))
rg.Select
If sSheetName <> "$$TOC" Then mg = mg & "Sheetname is not $$TOC" & CRLF
If sActiveCell <> "$$TOC" Then mg = mg & "Selected cell value is not $$TOC" & CRLF
If mg <> "" Then
mg = "Warning BuildTOC will destructively rewrite the selected area" _
& CRLF & CRLF & mg & CRLF & "Press OK to proceed, " _
& "the affected area will be rewritten, or" & CRLF & _
"Press CANCEL to check area then reinvoke this macro (BuildTOC)"
Application.ScreenUpdating = True 'make range visible
Reply = MsgBox(mg, vbOKCancel, "Create TOC for " & ActiveWorkbook.Sheets.Count _
& " items in workbook" & Chr(10) & "revised will now occupy up to 10 columns")
Application.ScreenUpdating = False
If Reply <> 1 Then GoTo AbortCode
End If
rg.Clear 'Clear out any previous hyperlinks, fonts, etc in the area
For cSht = 1 To ActiveWorkbook.Sheets.Count
Cells(cRow - 1 + cSht, cCol) = "'" & Sheets(cSht).Name
If TypeName(Sheets(cSht)) = "Worksheet" Then
'hypName = "'" & Sheets(csht).Name
' qSht = Replace(Sheets(cSht).Name, """", """""") -- replace not in XL97
qSht = Application.Substitute(Sheets(cSht).Name, """", """""")
If CDbl(Application.Version) < 8# Then
'-- use next line for XL95
Cells(cRow - 1 + cSht, cCol + 2) = "'" & Sheets(cSht).Name 'XL95
Else
'-- Only for XL97, XL98, XL2000 -- will create hyperlink & codename
Cells(cRow - 1 + cSht, cCol + 2) = "'" & Sheets(cSht).CodeName
'--- excel is not handling lots of objects well ---
'ActiveSheet.Hyperlinks.Add Anchor:=Cells(cRow - 1 + cSht, cCol), _
' Address:="", SubAddress:="'" & Sheets(cSht).Name & "'!A1"
'--- so will use the HYPERLINK formula instead ---
'--- =HYPERLINK("[VLOOKUP.XLS]'$$TOC'!A1","$$TOC")
ActiveSheet.Cells(cRow - 1 + cSht, cCol).Formula = _
"=hyperlink(""[" & ActiveWorkbook.Name _
& "]'" & qSht & "'!A1"",""" & qSht & """)"
End If
Else
Cells(cRow - 1 + cSht, cCol + 2) = "'" & Sheets(cSht).Name
End If
Cells(cRow - 1 + cSht, cCol + 1) = TypeName(Sheets(cSht))
' -- activate next line to include content of cell A1 for each sheet
' Cells(cRow - 1 + csht, cCol + 3) = Sheets(Sheets(csht).Name).Range("A1").Value
On Error Resume Next
Cells(cRow - 1 + cSht, cCol + 6) = Sheets(cSht).ScrollArea '.Address(0, 0)
Cells(cRow - 1 + cSht, cCol + 7) = Sheets(cSht).PageSetup.PrintArea
If TypeName(Sheets(cSht)) <> "Worksheet" Then GoTo byp7
Set lastcell = Sheets(cSht).Cells.SpecialCells(xlLastCell)
Cells(cRow - 1 + cSht, cCol + 4) = lastcell.Address(0, 0)
Cells(cRow - 1 + cSht, cCol + 5) = lastcell.Column * lastcell.Row
byp7: 'xxx
On Error GoTo 0
Next cSht
'Now sort the results: 2. Type(D), 1. Name (A), 3. module(unsorted)
rg.Sort Key1:=rg.Cells(1, 2), Order1:=xlDescending, Key2:=rg.Cells(1, 1) _
, Order2:=xlAscending, Header:=xlNo, OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
rg.Columns.AutoFit
rg.Select 'optional
'if cells above range are blank want these headers
' Worksheet, Type, codename
If cRow > 1 Then
If "" = Trim(Cells(cRow - 1, cCol) & Cells(cRow - 1, cCol + 1) & Cells(cRow - 1, cCol + 2)) Then
Cells(cRow - 1, cCol) = "Worksheet"
Cells(cRow - 1, cCol + 1) = "Type"
Cells(cRow - 1, cCol + 2) = "CodeName"
Cells(cRow - 1, cCol + 3) = "[opt.]"
Cells(cRow - 1, cCol + 4) = "Lastcell"
Cells(cRow - 1, cCol + 5) = "cells"
Cells(cRow - 1, cCol + 6) = "ScrollArea"
Cells(cRow - 1, cCol + 7) = "PrintArea"
End If
End If
Application.ScreenUpdating = True
Reply = MsgBox("Table of Contents created." & CRLF & CRLF & _
"Would you like the tabs in workbook also sorted", _
vbOKCancel, "Option to Sort " & ActiveWorkbook.Sheets.Count _
& " tabs in workbook")
Application.ScreenUpdating = False
'If Reply = 1 Then SortALLSheets 'Invoke macro to Sort Sheet Tabs
Sheets(sSheetName).Activate
AbortCode:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
I had created a Macro that reads data from a sheet and create journal entries. I had to update the macro due to some changes to the spreadsheet however now my macro doesnt work.
My macro works if I step through the entire thing or if I hit the play button in the VSB screen. However If I hit the macro button I embedded in spreadsheet, it breaks. I believe its breaking because its skipping this section:
If Cells(iRow2, 1) = "CCC $" Then
wsUp.Cells(iRow2, 1).Value = "CC"
ElseIf Cells(iRow2, 1) = "DDD $" Then
I am not sure why it is skipping this only when I bit the embedded button and not when I run it from the VSB screen.
Sub CreateAllocations_JEs()
Dim iRow As Integer, iCol As Integer, iRow2 As Integer
Dim sEntity As String, sEnt2 As String, sVal1 As String, sEnt3 As String, sDesc2 As String
Dim wsEntry As Worksheet
Dim wsUp As Worksheet
Dim wsInst As Worksheet
Set wsInst = Worksheets("Instructions")
Set wsEntry = Worksheets("Entries")
Set wsUp = Worksheets("Sheet1")
Dim lastrow As Long
Dim sRange As Range
Dim sQLNE As Long
''' Creates expense for holdings
For iRow = 6 To 35
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
sEntity = wsEntry.Range("D5").Value
sAcct = wsEntry.Range("N" & iRow).Value
sAcct2 = wsEntry.Range("M" & iRow).Value
sDesc = wsEntry.Range("O" & iRow).Value
vsum = Application.WorksheetFunction.Sum(wsEntry.Range("E" & iRow & ":J" & iRow))
If vsum > 0 Then
wsUp.Range("A" & lastrow + 1).Value = sEntity
wsUp.Range("J" & lastrow + 1).Value = vsum
wsUp.Range("G" & lastrow + 1).Value = sAcct
''''' Adds description column using the companies that have payables
sDesc2 = ""
End If
For iCol = 5 To 12
If wsEntry.Cells(iRow, iCol) > 0 Then
sEnt3 = wsEntry.Cells(5, iCol).Value
If sDesc2 <> "" Then
sDesc2 = sDesc2 & ", "
End If
sDesc2 = sDesc2 & sEnt3
End If
Next iCol
wsUp.Range("M" & lastrow + 1).Value = sDesc & sDesc2
'''''' Creates receivable for holdings and related fields
For iCol = 5 To 10
If wsEntry.Cells(iRow, iCol) > "0" Then
sVal1 = wsEntry.Cells(iRow, iCol).Value
sDesc = wsEntry.Range("O" & iRow).Value
sEnt3 = wsEntry.Cells(5, iCol).Value
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
wsUp.Range("A" & lastrow + 1).Value = sEntity
wsUp.Range("I" & lastrow + 1).Value = sVal1
vRec = Application.WorksheetFunction.Index(Sheets("IC accounts").Range("C:C"), Application.WorksheetFunction.Match(Sheets("Entries").Cells(5, iCol), Sheets("IC accounts").Range("B:B"), 0), 1)
wsUp.Range("G" & lastrow + 1).Value = vRec
wsUp.Range("M" & lastrow + 1).Value = sDesc & sEnt3
End If
Next iCol
''''Creates the payables and expense in other companies
For iCol = 5 To 12
If wsEntry.Cells(iRow, iCol) > "0" Then
sEnt2 = wsEntry.Cells(5, iCol).Value
sval2 = wsEntry.Cells(iRow, iCol).Value
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
wsUp.Range("A" & lastrow + 1, "A" & lastrow + 2).Value = sEnt2
If wsUp.Range("A" & lastrow + 1).Value = "AAA $" Then
wsUp.Range("J" & lastrow + 1).Value = sval2
wsUp.Range("I" & lastrow + 2).Value = sval2
wsUp.Range("G" & lastrow + 1).Value = sAcct2
wsUp.Range("G" & lastrow + 2).Value = "00-1320001"
ElseIf wsUp.Range("A" & lastrow + 1).Value = "BBB $" Then
wsUp.Range("J" & lastrow + 1).Value = sval2
wsUp.Range("I" & lastrow + 2).Value = sval2
wsUp.Range("G" & lastrow + 1).Value = sAcct2
wsUp.Range("G" & lastrow + 2).Value = "00-1320002"
Else
wsUp.Range("I" & lastrow + 1).Value = sval2
wsUp.Range("J" & lastrow + 2).Value = sval2
wsUp.Range("G" & lastrow + 1).Value = sAcct2
wsUp.Range("G" & lastrow + 2).Value = "00-4100040"
End If
wsUp.Range("M" & lastrow + 1, "M" & lastrow + 2).Value = sDesc & sEntity
End If
Next iCol
Next iRow
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
For iRow2 = 2 To lastrow
If Cells(iRow2, 1) = "CCC $" Then
wsUp.Cells(iRow2, 1).Value = "CC"
ElseIf Cells(iRow2, 1) = "DDD $" Then
wsUp.Cells(iRow2, 1).Value = "DD"
ElseIf Cells(iRow2, 1) = "EEE $" Then
wsUp.Cells(iRow2, 1).Value = "EE"
ElseIf Cells(iRow2, 1) = "FFF $" Then
wsUp.Cells(iRow2, 1).Value = "FF"
ElseIf Cells(iRow2, 1) = "GGG $" Then
wsUp.Cells(iRow2, 1).Value = "GG"
ElseIf Cells(iRow2, 1) = "HHH $" Then
wsUp.Cells(iRow2, 1).Value = "LLL"
ElseIf Cells(iRow2, 1) = "AAA $" Then
wsUp.Cells(iRow2, 1).Value = "LLL"
ElseIf Cells(iRow2, 1) = "LLL $" Then
wsUp.Cells(iRow2, 1).Value = "LLL"
ElseIf Cells(iRow2, 1) = "JJJ $" Then
wsUp.Cells(iRow2, 1).Value = "JJ"
End If
wsUp.Activate
Code Breaks Here. I beleive because skips section above.
vCN =
Application.WorksheetFunction.Index(Sheets("Company").Range("B:B"),
Application.WorksheetFunction.Match(Sheets("Sheet1").Cells(iRow2, 1),
Sheets("Company").Range("A:A"), 0), 1)
wsUp.Range("B" & iRow2).Value = vCN
vAN = Application.WorksheetFunction.Index(Sheets("COA").Range("B:B"),
Application.WorksheetFunction.Match(Sheets("Sheet1").Cells(iRow2, 7),
Sheets("COA").Range("A:A"), 0), 1)
wsUp.Range("H" & iRow2).Value = vAN
sQLNE = wsUp.Cells(Rows.Count, "N").End(xlUp).Row
wsUp.Range("N" & iRow2).Value = sQLNE
wsUp.Range("S" & iRow2).Value = wsUp.Range("I" & iRow2).Value
wsUp.Range("T" & iRow2).Value = wsUp.Range("J" & iRow2).Value
Next iRow2
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
sBatch = wsInst.Cells(8, 2).Value
sMonth = wsInst.Cells(6, 2).Value
sYear = wsInst.Cells(7, 2).Value
sDate = wsInst.Cells(5, 2).Value
sRef = sBatch & sMonth & sYear
wsUp.Range("C2", "C" & lastrow).Value = sRef
wsUp.Range("f2", "F" & lastrow).Value = sRef
wsUp.Range("D2", "D" & lastrow).Value = "1"
wsUp.Range("e2", "E" & lastrow).Value = "0"
wsUp.Range("K2", "k" & lastrow).Value = sDate
wsUp.Range("I:J").NumberFormat = "0.00"
wsUp.Range("S:T").NumberFormat = "0.00"
For iRow2 = 2 To lastrow
If Cells(iRow2, 9) = "" Then
wsUp.Cells(iRow2, 9).Value = "0.00"
wsUp.Cells(iRow2, 19).Value = "0.00"
ElseIf Cells(iRow2, 10) = "" Then
wsUp.Cells(iRow2, 10).Value = "0.00"
wsUp.Cells(iRow2, 20).Value = "0.00"
End If
Next iRow2
wsInst.Activate
End Sub
The code skips your if block because the parent for the cell has not been mentioned so it uses the activesheet, you have to explicitly mention that so instead of
If Cells(iRow2, 1) = "CCC $" Then
by this line:
MySheet.Cells(iRow2, 1) = "CCC $" Then
I don't know which one of the sheets is MySheet in your code, so replace it yourself
I have a function that maps data from one sheet (where it has been copied) to another which is then used for further analysis. When I run the code with screen updating on it always works fine. When I turn screen updating off the code gets stuck in an infinite loop in the last part of the sub (highlighted in bold - it is the inner most loop of the final section of code). If you then debug the code and re-start it continues normally and finished the code. If left it will never end, but next time will work fine:
Sub simsMap()
Dim simsCol As String
Dim mapCol As String
range("A5:OP253").ClearContents
range("S1:OP1").ClearContents
range("S4:OP4").ClearContents
simsCol = range("A1")
For x = 2 To 250
If Worksheets("simsData").range(simsCol & x) <> "" Then range("A" & x + 3).Value = Worksheets("simsData").range(simsCol & x)
Next x
simsCol = range("B1")
For x = 2 To 250
If range("A" & x + 3) <> "" Then
If Worksheets("simsData").range(simsCol & x) = range("B2") Or Worksheets("simsData").range(simsCol & x) = range("B3") Then
range(simsCol & x + 3) = "Y"
Else
range(simsCol & x + 3) = "N"
End If
End If
Next x
Dim simsArray As Variant
Dim mapArray As Variant
simsArray = Array("C1", "D1", "G1")
mapArray = Array("C", "D", "G")
For y = 0 To UBound(simsArray)
simsCol = range(simsArray(y))
mapCol = mapArray(y)
For x = 2 To 250
If range("A" & x + 3) <> "" Then
If Worksheets("simsData").range(simsCol & x) = "Y" Then
range(mapCol & x + 3) = "Y"
Else
range(mapCol & x + 3) = "N"
End If
End If
Next x
Next y
simsArray = Array("E1", "F1", "H1", "I1", "J1", "K1", "L1", "M1", "N1", "O1", "P1", "Q1")
mapArray = Array("E", "F", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q")
For y = 0 To UBound(simsArray)
simsCol = range(simsArray(y))
mapCol = mapArray(y)
For x = 2 To 250
If range("A" & x + 3) <> "" Then
range(mapCol & x + 3) = Worksheets("simsData").range(simsCol & x)
End If
Next x
Next y
Dim realColumn As String
Dim valueColumn As String
Dim columnNumber As Long
Dim realCell As String
Dim valueCell As String
Dim subjectJump As Integer
realColumn = "S"
subjectJump = 8 - Worksheets("menu").range("F17")
For y = 1 To 48
If Worksheets("menu").range("F19") = "Y" Then
valueColumn = range(realColumn & 1)
realCell = realColumn & 1
realColumn = Split(Cells(1, range(realCell).Column + 1).Address, "$")(1)
range(realColumn & 1) = valueColumn
For x = 1 To Worksheets("menu").range("F17")
valueCell = range(realColumn & 1) & 1
If range(realColumn & 1) <> "" Then valueColumn = Split(Cells(1, range(valueCell).Column + 1).Address, "$")(1)
realCell = realColumn & 1
realColumn = Split(Cells(1, range(realCell).Column + 1).Address, "$")(1)
range(realColumn & 1) = valueColumn
Next x
Else
If range(realColumn & 1) = "" Then
realCell = realColumn & 1
realColumn = Split(Cells(1, range(realCell).Column + 8).Address, "$")(1)
Else
For x = 1 To Worksheets("menu").range("F17")
valueCell = range(realColumn & 1) & 1
valueColumn = Split(Cells(1, range(valueCell).Column + 1).Address, "$")(1)
realCell = realColumn & 1
realColumn = Split(Cells(1, range(realCell).Column + 1).Address, "$")(1)
range(realColumn & 1) = valueColumn
Next x
realCell = realColumn & 1
realColumn = Split(Cells(1, range(realCell).Column + subjectJump).Address, "$")(1)
End If
End If
Next y
realColumn = "S"
For y = 1 To 384
simsCol = range(realColumn & 1)
mapCol = realColumn
If range(mapCol & 1) <> "" Then
If range("A" & 4) <> "" Then
range(mapCol & 4) = Worksheets("simsData").range(simsCol & 1)
End If
End If
realColumn = Split(Cells(1, range(realColumn & 1).Column + 1).Address, "$")(1)
Next y
realColumn = "S"
For y = 1 To 384
simsCol = range(realColumn & 1)
mapCol = realColumn
If range(mapCol & 1) <> "" Then
For x = 2 To 250
**If range("A" & x + 3) <> "" Then
range(mapCol & x + 3) = Left(Worksheets("simsData").range(simsCol & x), 1)
End If**
Next x
End If
realColumn = Split(Cells(1, range(realColumn & 1).Column + 1).Address, "$")(1)
If y = 384 Then loopCheck = False
Next y
For x = 5 To 253
If range("A" & x) <> "" Then studentNumber = x
Next x
End Sub
I have an excel file with 208 sheets and a summary sheet. Want to create a button to jump to each sheet. i am using the below codes for that.
Sub SearchSheetName()
Dim xName As String
Dim xFound As Boolean
xName = InputBox("Enter sheet name to find in workbook:", "Sheet search")
If xName = "" Then Exit Sub
On Error Resume Next
ActiveWorkbook.Sheets(xName).Select
xFound = (Err = 0)
On Error GoTo 0
If xFound Then
MsgBox "Sheet '" & xName & "' has been found and selected!"
Else
MsgBox "The sheet '" & xName & "' could not be found in this workbook!"
End If
End Sub
Going back to Summary sheet is difficult. so created macro with button
Private Sub CommandButton1_Click()
Sheets("SummarySheet").Select
End Sub
is there any easy way to create this button in all the sheets together.
I will add a button or shape (they are more pleasing in terms of cosmetics) to the sheet dynamically when its activated. Use Workbook's SheetActivate event to apply this to all the worksheets in the workbook.
In the WorkBook's SheetActivate add this
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Call addButton
End Sub
VBA code in a standard module:
Sub addButton()
'/ Dynamically add a semi-transparent shape on the active sheet.
'/ Call this inside workbooks SheetActivate event
Dim shp As Shape
Const strButtonName As String = "BackButton"
'/ Dont't add on summary sheet.
If ActiveSheet.Name = "Summary" Then Exit Sub
Application.ScreenUpdating = False
'/ Delete if old shape exists
For Each shp In ActiveSheet.Shapes
If shp.Name = strButtonName Then
shp.Delete
End If
Next
ActiveSheet.Shapes.AddShape(msoShapeRectangle, 330.75, 36.75, 93.75, 29.25).Select
Selection.Name = "BackButton"
Set shp = ActiveSheet.Shapes(strButtonName)
'/ Some formatting for the shape.
With shp
.TextFrame.Characters.Text = "Summary"
.Top = 3
.Left = 3
.Fill.Transparency = 0.6
.Line.Visible = msoTrue
.Line.ForeColor.RGB = RGB(0, 112, 192)
.TextFrame2.VerticalAnchor = msoAnchorMiddle
'/ Add the macro to shape's click. This will active summary sheet.
shp.OnAction = "goBack"
End With
ActiveSheet.Cells(1, 1).Select
Application.ScreenUpdating = True
End Sub
Sub goBack()
ThisWorkbook.Worksheets("Summary").Select
End Sub
This sounds like a Table of Contents (TOC) question. Copy/paste the code below and see if it does essentially what you want.
Option Explicit
Sub Macro1()
Dim i As Integer
Dim TOC As String
Dim msg As String
Dim fc_order As Range
Dim fc_alphabet As Range
Dim sht As Object
TOC = "Table of Contents"
For i = 1 To ActiveWorkbook.Worksheets.Count
If Worksheets(i).Name = TOC Then
msg = Chr(10) & Chr(10) & "Your sheet " & Chr(10) & TOC & Chr(10) & "(now displayed) will be updated."
Worksheets(TOC).Activate
Exit For
Else
msg = "A new sheet will be added :" & TOC & ", with hyperlinks to all sheets in this workbook."
End If
Next i
If MsgBox(msg & Chr(10) & "Do you want to continue ?", 36, TOC) = vbNo Then Exit Sub
Application.ScreenUpdating = False
Application.DisplayAlerts = False
If ActiveSheet.Name = TOC Then Worksheets(TOC).Delete
Worksheets(1).Activate
Worksheets.Add.Name = TOC
Cells.Interior.ColorIndex = 15
ActiveWindow.DisplayHeadings = False
With Cells(2, 6)
.Value = UCase(TOC)
.Font.Size = 18
.HorizontalAlignment = xlCenter 'verspreid over blad breedte
End With
Set fc_order = Cells(3, 4)
Set fc_alphabet = Cells(3, 8)
fc_order = "order of appearance"
For i = 2 To ActiveWorkbook.Worksheets.Count
If i Mod 30 = 0 Then
ActiveSheet.Hyperlinks.Add Anchor:=fc_order.Offset(i - 1, -2), Address:="", _
SubAddress:="'" & Worksheets(TOC).Name & "'!A1", TextToDisplay:="TOP"
End If
ActiveSheet.Hyperlinks.Add Anchor:=Cells(i + 2, 4), Address:="", _
SubAddress:=Worksheets(i).Name & "!A1", TextToDisplay:=Worksheets(i).Name
Next i
fc_alphabet = "alphabetically"
Range(fc_order.Offset(1, 0), fc_order.End(xlDown)).Copy fc_alphabet.Offset(1, 0)
Range(fc_alphabet.Offset(1, 0), fc_alphabet.End(xlDown)).Sort Key1:=fc_alphabet.Offset(1, 0)
If MsgBox("Do you want a hyperlink to " & TOC & " on each sheet in cell A1 ?" & Chr(10) & _
"(if cell A1 is empty)", 36, "Hyperlink on each sheet") = vbYes Then
For Each sht In Worksheets
sht.Select
If Cells(1, 1) = "" And sht.Name <> TOC Then ActiveSheet.Hyperlinks.Add Anchor:=Cells(1, 1), Address:="", _
SubAddress:="'" & Worksheets(TOC).Name & "'!A1", TextToDisplay:="TOC"
Next sht
End If
Sheets(TOC).Activate
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
The script below is similar, but somewhat different, to the one above.
Sub BuildTOC()
'listed from active cell down 7-cols -- DMcRitchie 1999-08-14 2000-09-05
Dim iSheet As Long, iBefore As Long
Dim sSheetName As String, sActiveCell As String
Dim cRow As Long, cCol As Long, cSht As Long
Dim lastcell
Dim qSht As String
Dim mg As String
Dim rg As Range
Dim CRLF As String
Dim Reply As Variant
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
cRow = ActiveCell.Row
cCol = ActiveCell.Column
sSheetName = UCase(ActiveSheet.Name)
sActiveCell = UCase(ActiveCell.Value)
mg = ""
CRLF = Chr(10) 'Actually just CR
Set rg = Range(Cells(cRow, cCol), Cells(cRow - 1 + ActiveWorkbook.Sheets.Count, cCol + 7))
rg.Select
If sSheetName <> "$$TOC" Then mg = mg & "Sheetname is not $$TOC" & CRLF
If sActiveCell <> "$$TOC" Then mg = mg & "Selected cell value is not $$TOC" & CRLF
If mg <> "" Then
mg = "Warning BuildTOC will destructively rewrite the selected area" _
& CRLF & CRLF & mg & CRLF & "Press OK to proceed, " _
& "the affected area will be rewritten, or" & CRLF & _
"Press CANCEL to check area then reinvoke this macro (BuildTOC)"
Application.ScreenUpdating = True 'make range visible
Reply = MsgBox(mg, vbOKCancel, "Create TOC for " & ActiveWorkbook.Sheets.Count _
& " items in workbook" & Chr(10) & "revised will now occupy up to 10 columns")
Application.ScreenUpdating = False
If Reply <> 1 Then GoTo AbortCode
End If
rg.Clear 'Clear out any previous hyperlinks, fonts, etc in the area
For cSht = 1 To ActiveWorkbook.Sheets.Count
Cells(cRow - 1 + cSht, cCol) = "'" & Sheets(cSht).Name
If TypeName(Sheets(cSht)) = "Worksheet" Then
'hypName = "'" & Sheets(csht).Name
' qSht = Replace(Sheets(cSht).Name, """", """""") -- replace not in XL97
qSht = Application.Substitute(Sheets(cSht).Name, """", """""")
If CDbl(Application.Version) < 8# Then
'-- use next line for XL95
Cells(cRow - 1 + cSht, cCol + 2) = "'" & Sheets(cSht).Name 'XL95
Else
'-- Only for XL97, XL98, XL2000 -- will create hyperlink & codename
Cells(cRow - 1 + cSht, cCol + 2) = "'" & Sheets(cSht).CodeName
'--- excel is not handling lots of objects well ---
'ActiveSheet.Hyperlinks.Add Anchor:=Cells(cRow - 1 + cSht, cCol), _
' Address:="", SubAddress:="'" & Sheets(cSht).Name & "'!A1"
'--- so will use the HYPERLINK formula instead ---
'--- =HYPERLINK("[VLOOKUP.XLS]'$$TOC'!A1","$$TOC")
ActiveSheet.Cells(cRow - 1 + cSht, cCol).Formula = _
"=hyperlink(""[" & ActiveWorkbook.Name _
& "]'" & qSht & "'!A1"",""" & qSht & """)"
End If
Else
Cells(cRow - 1 + cSht, cCol + 2) = "'" & Sheets(cSht).Name
End If
Cells(cRow - 1 + cSht, cCol + 1) = TypeName(Sheets(cSht))
' -- activate next line to include content of cell A1 for each sheet
' Cells(cRow - 1 + csht, cCol + 3) = Sheets(Sheets(csht).Name).Range("A1").Value
On Error Resume Next
Cells(cRow - 1 + cSht, cCol + 6) = Sheets(cSht).ScrollArea '.Address(0, 0)
Cells(cRow - 1 + cSht, cCol + 7) = Sheets(cSht).PageSetup.PrintArea
If TypeName(Sheets(cSht)) <> "Worksheet" Then GoTo byp7
Set lastcell = Sheets(cSht).Cells.SpecialCells(xlLastCell)
Cells(cRow - 1 + cSht, cCol + 4) = lastcell.Address(0, 0)
Cells(cRow - 1 + cSht, cCol + 5) = lastcell.Column * lastcell.Row
byp7: 'xxx
On Error GoTo 0
Next cSht
'Now sort the results: 2. Type(D), 1. Name (A), 3. module(unsorted)
rg.Sort Key1:=rg.Cells(1, 2), Order1:=xlDescending, Key2:=rg.Cells(1, 1) _
, Order2:=xlAscending, Header:=xlNo, OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
rg.Columns.AutoFit
rg.Select 'optional
'if cells above range are blank want these headers
' Worksheet, Type, codename
If cRow > 1 Then
If "" = Trim(Cells(cRow - 1, cCol) & Cells(cRow - 1, cCol + 1) & Cells(cRow - 1, cCol + 2)) Then
Cells(cRow - 1, cCol) = "Worksheet"
Cells(cRow - 1, cCol + 1) = "Type"
Cells(cRow - 1, cCol + 2) = "CodeName"
Cells(cRow - 1, cCol + 3) = "[opt.]"
Cells(cRow - 1, cCol + 4) = "Lastcell"
Cells(cRow - 1, cCol + 5) = "cells"
Cells(cRow - 1, cCol + 6) = "ScrollArea"
Cells(cRow - 1, cCol + 7) = "PrintArea"
End If
End If
Application.ScreenUpdating = True
Reply = MsgBox("Table of Contents created." & CRLF & CRLF & _
"Would you like the tabs in workbook also sorted", _
vbOKCancel, "Option to Sort " & ActiveWorkbook.Sheets.Count _
& " tabs in workbook")
Application.ScreenUpdating = False
'If Reply = 1 Then SortALLSheets 'Invoke macro to Sort Sheet Tabs
Sheets(sSheetName).Activate
AbortCode:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Sub BuildTOC_A3()
Cells(3, 1).Select
BuildTOC
End Sub
I have 2 Excel sheets, I need to take 1 value in Sheet 1, look for it in Sheet 2. If I find it, then I need to make sure that some other values are matching. If yes, I copy the sheet 1 row in a "match" tab.
If not, I copy the row in "mismatch" tab and I need to insert a message that says which value didn't match.
I cannot make it work right now. I think I'm not exiting the loop in the right place. Here is my code. If anybody could help, I would appreciate.
Sub compareAndCopy()
Dim LastRowISINGB As Integer
Dim LastRowISINNR As Integer
Dim lastRowM As Integer
Dim lastRowN As Integer
Dim foundTrue As Boolean
Dim ErrorMsg As String
' stop screen from updating to speed things up
Application.ScreenUpdating = False
'Find the last row for column F and Column B from Sheet 1 and Sheet 2
LastRowISINGB = Sheets("Sheet1").Cells(Sheets("Sheet1").Rows.Count, "f").End(xlUp).row
LastRowISINNR = Sheets("Sheet2").Cells(Sheets("Sheet2").Rows.Count, "b").End(xlUp).row
'fIND THE LAST ROW OF MATCH AND MISMATCH TAB
lastRowM = Sheets("mismatch").Cells(Sheets("mismatch").Rows.Count, "f").End(xlUp).row + 1
lastRowN = Sheets("match").Cells(Sheets("match").Rows.Count, "f").End(xlUp).row + 1
'ISIN MATCH FIRST
For I = 2 To LastRowISINGB
For J = LastRowISINNR To 2 Step -1
If Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value = "Y" And _
Worksheets("Sheet2").Range("Z" & J).Value = "" And _
(Worksheets("Sheet1").Range("c" & I).Value = Worksheets("Sheet2").Range("AF" & J).Value Or _
Worksheets("Sheet1").Range("K" & I).Value = Worksheets("Sheet2").Range("K" & J).Value Or _
Worksheets("Sheet1").Range("N" & I).Value = Worksheets("Sheet2").Range("L" & J).Value) Then
Sheets("Sheet1").Rows(I).Copy Destination:=Sheets("match").Rows(lastRowN)
lastRowN = lastRowN + 1
Exit For
ElseIf Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value = "Y" And _
Worksheets("Sheet2").Range("Z" & J).Value = "" And _
Worksheets("Sheet1").Range("c" & I).Value <> Worksheets("Sheet2").Range("AF" & J).Value And _
Worksheets("Sheet1").Range("K" & I).Value <> Worksheets("Sheet2").Range("K" & J).Value And _
Worksheets("Sheet1").Range("N" & I).Value <> Worksheets("Sheet2").Range("L" & J).Value Then
ErrorMsg = "dates don't match"
ElseIf Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value <> "Y" Then
ErrorMsg = "B column don't match"
ElseIf Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value = "Y" And _
Worksheets("Sheet2").Range("Z" & J).Value <> "" Then
ErrorMsg = "Z column don't match"
Else: ErrorMsg = "ISIN don't match"
End If
Next J
Sheets("Sheet1").Rows(I).Copy Destination:=Sheets("mismatch").Rows(lastRowM)
Worksheets("mismatch").Range("S" & lastRowM).Value = ErrorMsg
lastRowM = lastRowM + 1
Next I
' stop screen from updating to speed things up
Application.ScreenUpdating = True
End Sub
First, I think you should add "Exit For" for each clause in If..else method. Otherwise it will lead to the fact that almost of your "miss match" result will be "ISIN don't match".
Second, I think you should set ErrorMsg = "" before For J = LastRowISINNR To 2 Step -1, and have condition ErrorMsg <> "" when you input result in sheet miss match.
Sheets("Sheet1").Rows(I).Copy Destination:=Sheets("mismatch").Rows(lastRowM)
Worksheets("mismatch").Range("S" & lastRowM).Value = ErrorMsg
lastRowM = lastRowM + 1
Otherwise, all your row even match or missmatch will input into miss match sheet.