I have a code that creates a hyperlink to a new worksheet that is created, in another worksheet called 'Management', in cell 'A6'. How can I code it so that every time I create a new sheet, the hyperlink is created to different cell? For example, A7, A8, A9 etc for each new sheet is created.
Here is the code I have so far
Private Sub Button8_Click()
Dim newSheet As Worksheet
Dim newName As String
Do
newName = Application.InputBox("What do you want to name the new sheet?", Type:=2)
If newName = "False" Then Exit Sub: Rem cancel pressed
Set newSheet = ThisWorkbook.Sheets.Add
On Error Resume Next
newSheet.Name = newName
newName = Error
On Error GoTo 0
If newName <> vbNullString Then
Application.DisplayAlerts = False
newSheet.Delete
Application.DisplayAlerts = True
MsgBox newName
End If
Loop Until newName = vbNullString
ThisWorkbook.Worksheets("Version Checklist").Cells.Copy
newSheet.Paste
Dim targetSheet As Worksheet
Dim targetRange As Range
Dim linkedSheet As Worksheet
Dim linkRange As Range
'set variable to the sheet the hyperlink will link to
Set targetSheet = ThisWorkbook.Sheets(ActiveSheet.Name)
' specify the range on the summary sheet to link to
Set targetRange = targetSheet.Range("A1:Z100")
' set variable to sheet that will have the hyperlink
Set linkedSheet = ThisWorkbook.Sheets("Management")
' specify where on that sheet we'll create the hyperlink
Set linkRange = linkedSheet.Range("A6")
' create the hypperlink on the copied sheet pointing
' back to the summary sheet
linkedSheet.Hyperlinks.Add Anchor:=linkRange, Address:="", SubAddress:= _
"'" & targetSheet.Name & "'!" & targetRange.Address, _
TextToDisplay:=targetSheet.Name
End sub
You could set a cell to be a permanent counter of the number of clicks you have gone through and use this value to determine the numerical portion of the cell address. Adding some code like this would help run the counter:
Sub counter()
Dim x As Range
Set x = Range("A1")
x = x + 1
Range("A1").Value = x
End Sub
Then you could write something like this for the hyperlink reference:
Set linkRange = linkedSheet.Range("A" & x)
Every time you click to make a new sheet your counter will go up and your cell reference will change.
Related
I have a list of items and a new sheet button like this:
For each item you have to be able to create new worksheet when you click on that button. It copies a worksheet from a template, one worksheet for a single row. Now i want to be able to copy some of the info from a row i select to that new worksheet cells when i click on the button and maybe rename the worksheet as a value in one of the cells (ID). The values i need are ID and name, maybe few more.
Sub AddNameNewSheet2()
Dim CurrentSheetName As String
CurrentSheetName = ActiveSheet.Name
'Add New Sheet
Dim i As Byte, sh As Worksheet
For i = 1 To 1
Sheets("Predlozak").Copy After:=Sheets("Predlozak")
Set sh = ActiveSheet
Next i
On Error Resume Next
'Get the new name
ActiveSheet.Name = InputBox("Name for new worksheet?")
'Keep asking for name if name is invalid - Here i want to change worksheet name to a specific cell value from selected row.
Do Until Err.Number = 0
Err.Clear
ActiveSheet.Name = InputBox("Try Again!" _
& vbCrLf & "Invalid Name or Name Already Exists" _
& vbCrLf & "Please name the New Sheet")
Loop
On Error GoTo 0
End Sub
Anyone has an idea how can i make this work?
Here's what I came up with, I also thought checkboxes would be a good way to pick the line, it's quite simple:
Sub AddNameNewSheet2()
Dim x As Long
Dim wks As Worksheet
Dim IdCell As Range, NamCell As Range, FormCell As Range
Set wks = ActiveSheet
Set IdCell = wks.Range("A:A").Find("TRUE").Offset(0, 1)
Set FormCell = IdCell.End(xlToRight)
Set NamCell = IdCell.Offset(0, 1)
Sheets.Add After:=Sheets(1), Type:= _
"C:\Users\*yournamehere*\AppData\Roaming\Microsoft\Templates\*yourtemplatehere*.xltm"
ActiveSheet.Name = NamCell
Dim wks2T As ListObject
Set wks2T = ActiveSheet.ListObjects(1)
With wks2T
.ListColumns(1).Range(2) = IdCell.Value
.ListColumns(2).Range(2).Value = NamCell.Value
.ListColumns(3).Range(2).Value = FormCell.Value
End With
End Sub
I made the template a table cause it is easier to specify exactly where to put stuff. And it is more manageable as more data is added in the future.
Sheet1 image
Sheet2 image
I need help modifying a macro that matches the part number (Column C) between two sheets in different workbooks. Then it pastes the info from 'Original' sheet from the range P9:X6500 into the 'New' sheet into the range P9:X6500. The first sheet 'Original' in column C range C9:C6500 is the matching part number column. The 'New' sheet has the same column C with the part number to match. I only want match and paste the visible values.
I originally had this macro code which copy pastes only visible values from one workbook to another that I would like to modify it to match and copy paste:
Sub GetDataDemo()
Const FileName As String = "Original.xlsx"
Const SheetName As String = "Original"
FilePath = "C:\Users\me\Desktop\"
Dim wb As Workbook
Dim this As Worksheet
Dim i As Long, ii As Long
Application.ScreenUpdating = False
If IsEmpty(Dir(FilePath & FileName)) Then
MsgBox "The file " & FileName & " was not found", , "File Doesn't Exist"
Else
Set this = ActiveSheet
Set wb = Workbooks.Open(FilePath & FileName)
With wb.Worksheets(SheetName).Range("P9:X500")
On Error Resume Next
.SpecialCells(xlCellTypeVisible).Copy this.Range("P9")
On Error GoTo 0
End With
End If
ThisWorkbook.Worksheets("NEW").Activate
End Sub
Also here is what I want it to look like:
Original
NEW
I appreciate the help!
try the following where it copies the range from one sheet to the other. You can break up With wb.Worksheets(SheetName).Range("P9:X500") into With wb.Worksheets(SheetName) then use .Range("P9:X500").Copy this.Range("P9") inside the With statement. Avoid using names like i or ii or this and use something more descriptive. The error handling is essentially only dealing with Sheets not being present and i think better handling of that scenario could be done. Finally, you need to turn ScreenUpdating back on to view changes.
Option Explicit
Public Sub GetDataDemo()
Const FILENAME As String = "Original.xlsx"
Const SHEETNAME As String = "Original"
Const FILEPATH As String = "C:\Users\me\Desktop\"
Dim wb As Workbook
Dim this As Worksheet 'Please reconsider this name
Application.ScreenUpdating = False
If IsEmpty(Dir(FILEPATH & FILENAME)) Then
MsgBox "The file " & FILENAME & " was not found", , "File Doesn't Exist"
Else
Set this = ActiveSheet
Set wb = Workbooks.Open(FILEPATH & FILENAME)
With wb.Worksheets(SHEETNAME)
'On Error Resume Next ''Not required here unless either of sheets do not exist
.Range("P9:X500").Copy this.Range("P9")
' On Error GoTo 0
End With
End If
ThisWorkbook.Worksheets("NEW").Activate
Application.ScreenUpdating = True ' so you can see the changes
End Sub
UPDATE: As OP wants to match between sheets on column C in both and paste associated row information across (Col P to Col X) second code version posted below
Version 2:
Option Explicit
Public Sub GetDataDemo()
Dim wb As Workbook
Dim lookupRange As Range
Dim matchRange As Range
Set wb = ThisWorkbook
Set lookupRange = wb.Worksheets("Original").Range("C9:C500")
Set matchRange = wb.Worksheets("ThisSheet").Range("C9:C500")
Dim lookupCell As Range
Dim matchCell As Range
With wb.Worksheets("Original")
For Each lookupCell In lookupRange
For Each matchCell In matchRange
If Not IsEmpty(matchCell) And matchCell = lookupCell Then 'assumes no gaps in lookup range
matchCell.Offset(0, 13).Resize(1, 9).Value2 = lookupCell.Offset(0, 13).Resize(1, 9).Value2
End If
Next matchCell
Next lookupCell
End With
ThisWorkbook.Worksheets("NEW").Activate
Application.ScreenUpdating = True
End Sub
You may need to amend a few lines to suit your environment e.g. change this to meet your sheet name (pasting to).
Set matchRange = wb.Worksheets("ThisSheet").Range("C9:C500")
So I have a dashboard sheet named "Business Plans" where I have a dropdown in cell A2 that's a dropdown selection of a range called "Facilities" and all dashboard data are driven off of lookups. What I want to do is First create a new workbook than a new tab for each dropdown selection with the tab in the same format but the data pasted as values. I attempted the following code that I created to save every dropdown selection as PDF but I have been unsuccessful. Any insight on how I can get this code working will be great.
Sub Worksheet_Generator()
Dim cell As Range
Dim wsSummary As Worksheet
Dim counter As Long
Set wsSummary = Sheets("Business Plans")
For Each cell In Worksheets("dd").Range("$C3:$C75")
If cell.Value = "" Then
counter = counter + 1
Application.StatusBar = "Processing file: " & counter & "/1042"
Else
counter = counter + 1
Application.StatusBar = "Processing file: " & counter & "/1042"
With wsSummary
.Range("$A$2").Value = cell.Value
ActiveSheet.Copy After:=Worksheets(Worksheets.Count)
ActiveSheet.Copy
With ActiveSheet.UsedRange
.Value = .Value
End With
End With
End If
Next cell
Set wsSummary = Nothing
End Sub
I think you are looking for something like the below (adapted from copying-dynamic-rows-into-new-workbook-and-save-it).
Option Explicit
Sub grabber()
Dim thisWb As Workbook: Set thisWb = ThisWorkbook
Dim thisWs As Worksheet: Set thisWs = thisWb.Worksheets("dd") 'replace with relevant name
Dim newBook As Workbook
Dim newws As Worksheet
Dim pathToNewWb As String
Dim uKeys
Dim currentPath, columnWithKey, numCols, numRows, uKey, dataStartRow, columnKeyName
'nobody likes flickering screens
Application.ScreenUpdating = False
'remove any filter applied to the data
thisWs.AutoFilterMode = False
'get the path of the workbook folder
currentPath = Application.ThisWorkbook.Path
'Set the stage
'###Hardcode###
columnKeyName = "Facility" 'name of the column with the facility values
dataStartRow = 4 'this is a pure guess, correct as relevenat. Use the header row index
pathToNewWb = currentPath & "/Business Plans.xlsx" ' where to put the new excel, if you want a saveas prompt you should google "Application.FileDialog(msoFileDialogSaveAs)"
uKeys = Range("Facilities").Value
'###Hardcode End###
columnWithKey = thisWs.Range(dataStartRow & ":" & dataStartRow).Find(what:=columnKeyName, LookIn:=xlValues).Column
numCols = thisWs.UsedRange.Columns.Count
'extract the index of the last used row in the worksheet
numRows = thisWs.UsedRange.Rows.Count
'create the new workbook
Set newBook = Workbooks.Add
'loop the facilities, and do the work
For Each uKey In uKeys
'Filter the keys column for a unique key
thisWs.Range(thisWs.Cells(dataStartRow, 1), thisWs.Cells(numRows, numCols)).AutoFilter field:=columnWithKey, Criteria1:=uKey
'copy the sheet
thisWs.UsedRange.Copy
'Create a new ws for the facility, and paste as values
Set newws = newBook.Worksheets.Add
With newws
.Name = uKey 'I assume the name of the facility is the relevant sheet name
.Range("A1").PasteSpecial xlPasteValues
End With
'remove autofilter (paranoid parrot)
thisWs.AutoFilterMode = False
Next uKey
'save the new workbook
newBook.SaveAs pathToNewWb
newBook.Close
End Sub
EDIT:
As I have not seen your data, I would not be surprised if it requires some revision.
First I try to "frame" the range of the worksheet "dd" that contains the data (the ###Hardcode### bit), define the path for the output, and identify the column that can be filtered for the values corresponding to the named range "Facilities".
I retrieve the values of the named range "Facilities" (into uKeys), and create the output workbook (newBook). Then we go through each value (uKey) from the uKeys in the for loop. Within the loop, I apply an autofilter for the uKey. The filtration is followed by creation of a sheet (newWs) in newBook, and a copy paste of the filtered worksheet "dd" into newWs. we then turn off the autofilter, and the worksheet "dd" is returned to its unfiltered state.
At the end we save newBook to the desired location, and close it.
I am fairly new with Excel vba but have been using access vba for some time now.
I have some code which splits a main file into several other files based on a distinct column in excel
Sub SplitbyValue()
Dim FromR As Range, ToR As Range, All As Range, Header As Range
Dim Wb As Workbook
Dim Ws As Worksheet
'Get the header in this sheet
Set Header = Range("D8").EntireRow
'Visit each used cell in column D, except the header
Set FromR = Range("D9")
For Each ToR In Range(FromR, Range("D" & Rows.Count).End(xlUp).Offset(1))
'Did the value change?
If FromR <> ToR Then
'Yes, get the cells between
Set All = Range(FromR, ToR.Offset(-1)).EntireRow
'Make a new file
Set Wb = Workbooks.Add(xlWBATWorksheet)
'Copy the data into there
With Wb.ActiveSheet
Header.Copy .Range("A8")
All.Copy .Range("A9")
End With
'Save it
Wb.SaveAs ThisWorkbook.Path & "\" & Format(Date, "yyyy.mm.dd") & _
" - " & FromR.Value & ".xls", xlWorkbookNormal
Wb.Close
'Remember the start of this section
Set FromR = ToR
End If
Next
End Sub
This works great for the main sheet, but have to copy multiple tabs and this only captures one sheet. How can I expand this so it copies the other sheets as well into that file?
example:
ColumnA
Id1
Id2
Id3
This creates three files (Id1)(Id2)(Id3) but ignores the other sheets.
Create an encompassing loop and define the worksheet being processed with a With...End With statement. You loop through a For Each...Next Statement using a Worksheet object on the Worksheets collection but I typically use the index of each worksheet.
Sub SplitbyValue()
Dim FromR As Range, ToR As Range, dta As Range, hdr As Range
Dim w As Long, ws As Worksheet, wb As Workbook, nuwb As Workbook
'Get the header in this sheet
Set wb = ActiveWorkbook
For w = 1 To wb.Worksheets.Count
With wb.Worksheets(w)
Set hdr = .Range(.Cells(8, "D"), .Cells(8, Columns.Count).End(xlToLeft))
'Visit each used cell in column D, except the header
Set FromR = .Range("D9")
For Each ToR In .Range(FromR, .Range("D" & Rows.Count).End(xlUp).Offset(1))
'Did the value change?
If FromR <> ToR Then
'Yes, get the cells between
Set dta = .Range(FromR, ToR.Offset(-1)).EntireRow
'Make a new file
Set nuwb = Workbooks.Add(xlWBATWorksheet)
'Copy the data into there
With nuwb.Sheet1
hdr.Copy .Range("A8")
dta.Copy .Range("A9")
End With
'Save it
nuwb.SaveAs ThisWorkbook.Path & "\" & Format(Date, "yyyy.mm.dd") & _
" - " & FromR.Value & ".xls", xlWorkbookNormal
nuwb.Close False
Set nuwb = Nothing
'Remember the start of this section
Set FromR = ToR
End If
Next ToR
End With
Next w
End Sub
I did not set up a full test environment but this should get you heading in the right direction. I've always found it unreliable to depend on ActiveSheet.
Here is a function that will allow you to search for a sheet and goto it by name.
Private Sub loopsheets(strSheetName As String)
iFoundWorksheet = 0
For iIndex = 1 To ea.ActiveWorkbook.Worksheets.Count
Set ws = ea.Worksheets(iIndex)
If UCase(ws.Name) = UCase(strSheetName) Then
iFoundWorksheet = iIndex
Exit For
End If
Next iIndex
If iFoundWorksheet = 0 Then
MsgBox "No worksheet was found with the name RESULTS (this is not case sensetive). Aborting."
End If
Set ws = ea.Worksheets(iFoundWorksheet)
ws.Activate
End Sub
If you want to just loop them all you just need the for loop.
Dim iIndex as Integer
For iIndex = 1 To ea.ActiveWorkbook.Worksheets.Count
Set ws = ea.Worksheets(iIndex)
ws.Activate
'Call your code here.
SplitbyValue
Next iIndex
I am trying to select a worksheet every time when i open up a workbook using an inputbox in VBA. here is my code for opening a workbook but after i open up my workbook, how do i select a worksheet inside that workbook?
Sub button7_click()
dim wb as string
dim ss as string
wb = Application.GetOpenFilename
if wb <> "False" Then Workbooks.Open wb
End sub
Assuming "Sheet1" is the name of the sheet that you want to select...
Workbooks(wb).Sheets("Sheet1").Select
EDIT: And you can use something like this to get a variable sheet name from an InputBox. In its simplest form...
Dim Result As String
Result = InputBox("Provide a sheet name.")
Workbooks(wb).Sheets(Result).Select
...but I would add some error handling into this also to prevent errors from blanks, misspelled or invalid sheet names.
Let's say you have a "normal", blank Excel workbook with sheets "Sheet1", "Sheet2" and "Sheet3". Now, when the workbook opens, let's assume you want to activate (not select, as that's different) the sheet called "Sheet2".
In your workbook's ThisWorkbook module, add this code:
Private Sub Workbook_Open()
ActiveWorkbook.Sheets("Sheet2").Activate
End Sub
Make sure this code is pasted inside of the ThisWorkbook object and not in a Module, Form, or Sheet object.
Save and exit the workbook. When you re-open it, "Sheet2" will be the active sheet.
Here is the final code if anyone wants it.
Multiple selections are not quite possible , as the copied worksheet only copies across and increments the largest value of the range selected rather than all the cells selected individually ....
Sub CopyAndIncrement()
Dim ws As Worksheet
Dim Count As Integer
Dim Rng As Range
Dim myValue As Integer
Dim wsName As String
wsName = InputBox("Provide the EXACT sheet name you want to copy.")
'error handling loop for Worksheet name
For p = 1 To Worksheets.Count
If Worksheets(p).Name = wsName Then
exists = True
End If
Next p
If Not exists Then
While exists = False
wsName = InputBox("Sheet not found re-enter name.")
For p = 1 To Worksheets.Count
If Worksheets(p).Name = wsName Then
exists = True
End If
Next p
Wend
End If
Set Rng = Application.InputBox( _
Title:="Increment your worksheet", _
Prompt:="Select a cell(s) you want to increment", _
Type:=8)
On Error GoTo 0
If Rng Is Nothing Then Exit Sub 'Test to ensure User Did not cancel
'Set Rng = Rng.Cells(1, 1) 'Set Variable to first cell in user's input (ensuring only
'1 cell) >> commenting this can give multiple selections
myValue = InputBox("How many time do you want it to increment? Give me the number ")
Do While Count < myValue
For Each ws In Worksheets ' this loop selects the last sheet in the workbook
LastWs = ws.Name
i = ws.Range(Rng.Address).Value
If i > j Then
j = i
End If
Next
Sheets(wsName).Select
Sheets(wsName).Copy After:=Sheets(LastWs)
ActiveSheet.Range(Rng.Address).Value = j + 1
Count = Count + 1
Loop
End Sub