Update all links at once - excel

I have a Workbook with many sheets almost all of them have a hyperlink to cell A1 in one specific sheet named 'HK 2017'. I want to change the name of the hyperlinked sheet from 'HK 2017' to 'HK'. And also update all links at once, so that they could work with the new name of the sheet.
Thanks for help.

Loop through the sheets in the worksheet. Excel VBA looping through multiple worksheets
In every sheet, loop through the cells in the used range. Excel VBA iterate over all used cells and substitute their values
Change their hyperlink values. changing a wildcard in an excel hyperlink with vba or Excel VBA Get hyperlink address of specific cell
Party like it's your birthday - https://www.youtube.com/watch?v=5qm8PH4xAss

Here is my solution. In all worksheets of the current workbook I simply replace a given string in the formula for a different one
Public Sub edit_links()
Dim iSheet As Worksheet
Dim old_text as string
Dim new_text as string
old_text = "='\\C\client\XYZ\[old_excel_file.xlsm]Sheet1'"
new_text = "=Sheet1"
For Each iSheet In ThisWorkbook.Sheets
'Debug.Print isheet.Name
Call update_all_cell_formulas_in_sheet( _
isheet, _
old_text, _
new_text)
Next iSheet
End Sub
private Sub update_all_cell_formulas_in_sheet(in_sheet As Worksheet, in_search As String, in_replace As String)
Dim counter As Integer
Dim iCell As Range
counter = 0
For Each iCell In in_sheet.UsedRange
If InStr(iCell.Formula, in_search) > 0 Then
counter = counter + 1
'Debug.Print iCell.Parent.Name, iCell.Address, iCell.Formula
iCell.Formula = Replace(iCell.Formula, in_search, in_replace)
'Debug.Assert counter Mod 100 <> 0 ' stop the code every 100 changes
End If
Next iCell
update_all_cell_formulas_in_sheet = counter
End Sub

Related

Why isn't this Vlookup loop macro working?

I am trying to write an Excel macro that will perform a VLOOKUP on cells 9:100 of column K on 1155 individual sheets (named Page 1, Page 2, etc) of a workbook. I want to run the macro in another workbook, though. So I'm trying to target the cells in one workbook to populate cell values in another.
I have this. However, when I run it, all it does is replace the contents of the specified cells on the first sheet with "#VALUE!". It doesn't do anything to the other sheets.
Sub SearchPages()
Dim i As Integer
Dim cell As Range
Dim value As Variant
Dim result As Variant
Dim wb As Workbook
Set wb = Workbooks.Open("file.xls")
For Each cell In Range("K9:K100")
value = cell.value
result = "Not Found"
For i = 1 To 1155
On Error Resume Next
result = Application.VLookup(value, "Page " & i & "!K:N", 4, False)
On Error GoTo 0
If Not IsError(result) Then
Exit For
End If
Next i
cell.value = result
Next cell
End Sub
Is what I'm trying to do even possible? Any insight is much appreciated!

Inserting a new sheet alphabetically between two specific sheets

So far, I have created a button "AddaSheet" which pops up a userform where a name "NewSheetName" can be inserted in a text box. Then I have a button ("AddNow") which when clicked, needs to (and this is where I need help) do the following:
copy the "Template" sheet and rename it as "NewSheetName" (so the inputted text) and insert this new sheet alphabetically between two defined sheets.
I have many sheets in my workbook with different elements such as tables and so on, and I have grouped a particular kind of data set sheets together. As such, Ideally, if the new sheet can be inputted between a set range, it would be great.
Thank you in advance for your help!
p.s. I am a beginner, I would really appreciate if you could explain with comments what the code is doing.
This will sort your sheets into alphabetical order
Sub SortSheetsTabName()
' Turn off screenupdating so no visual effects to enduser
Application.ScreenUpdating = False
Dim iSheets%, i%, j%
' Get number of sheets in workbook
iSheets = Sheets.Count
' Loop through all sheets in workbook
For i = 1 To iSheets - 1
' Loop through sheets to find correct position of worksheet
For j = i + 1 To iSheets
' Test position
If Sheets(j).Name < Sheets(i).Name Then
' Move sheet to alphabetical position
Sheets(j).Move before:=Sheets(i)
End If
Next j
Next i
' Turn on screenupdating for end user
Application.ScreenUpdating = True
End Sub
Source
If you need to insert the new sheet alphabetically between two defined sheets. For example between a sheet called Start and a sheet called End then use the following code.
The advantage of this code is that there can be a alphabetically random order of sheets before Start and after End but only the new template sheet gets sorted in the correct way.
Example:
In the following sheets the new Delta sheet will be sorted in between Beta and Epsilon but the rest of the order is completely random:
Option Explicit
Public Sub CopyAndSortSheetInBetween()
Dim wsTemplate As Worksheet 'template sheet
Set wsTemplate = ThisWorkbook.Worksheets("Template")
Dim iStart As Long 'define your start sheet
iStart = ThisWorkbook.Sheets("Start").Index + 1
Dim iEnd As Long 'define your end sheet
iEnd = ThisWorkbook.Sheets("Stop").Index - 1
If iEnd < iStart Then
MsgBox "Stop sheet is before start sheet"
Exit Sub
End If
Dim NewName As String 'name that your new sheet will be
NewName = "Delta"
'find out which position is between "Start" and "Stop" sheet is the correct
Dim i As Long
For i = iStart To iEnd
If UCase(ThisWorkbook.Sheets(i).Name) > UCase(NewName) Then
Exit For
End If
Next i
'now i is the destination sheet number for your copied template sheet
'and you can copy and rename your template
wsTemplate.Copy Before:=ThisWorkbook.Sheets(i)
ThisWorkbook.Sheets(i).Name = NewName
End Sub

SUMPRODUCT formula with changing number of worksheets

I have an Excel workbook with multiple worksheets and I would like to use SUMPRODUCT formula to sum values from all worksheets with name Page 1, Page 1(2), Page 1(3), Page 1(4) etc.:
=SUMPRODUCT(SUMIF(INDIRECT("'"&D2:D4&"'!B11:B100"),$B3,INDIRECT("'"&D2:D4&"'!E11:E100")))
The problem is that the number of Page 1 worksheets is different every time and I need to update &D2:D4& every time manually. Is there any way I could automate it so I don't need to change the range manually?
Please paste the code below in the ThisWorkbook code sheet of the workbook in which you have your SUMPRODUCT formula. Then adjust the code to comply with the comments I added into it (especially with regard to the name of the worksheet on which you have the range D2:D4.
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
SetPageRange
End Sub
Private Sub SetPageRange()
' this procedure creates a named range "Pages" which you can
' use in your formula instead of "D2:D4"
' =SUMPRODUCT(SUMIF(INDIRECT("'"& Pages &"'!B11:B100"),$B3,INDIRECT("'"& Pages &"'!E11:E100")))
Const WsName As String = "Page" 'Page, Page (1), Page(x)
' change to "Page 1" if that is what you need
Dim Wb As Workbook
Dim MasterWs As Worksheet
Dim Arr() As String
Dim i As Integer
Dim Ws As Worksheet
' the Active workbook is not necessarily the workbook containing this code !!
Set Wb = ActiveWorkbook
ReDim Arr(1 To 20) ' maximum number of sheets you expect
' this number of rows must be available
' below D2 in the sheet where your
' formula resides
For Each Ws In Wb.Worksheets
' this collects all sheets whose name starts with "Page"
If InStr(1, Ws.Name, WsName, vbTextCompare) = 1 Then
i = i + 1
Arr(i) = Ws.Name
End If
Next Ws
' Change the name "Sheet5" to the name of the sheet where your
' SUMPRODUCT formula resides and where you currently have D2:D4
' if it isn't in the ActiveWorkbook, then where is it?
Set MasterWs = Wb.Worksheets("Sheet5")
With MasterWs.Cells(2, "D") ' this is where the names will be written
' from D2 down (20 rows, as set above)
.Resize(UBound(Arr)).Value = Application.Transpose(Arr)
Wb.Names.Add Name:="Pages", RefersTo:="=" & .Resize(i).Address(True, True, xlA1, True)
End With
End Sub
Save the workbook as macro-enabled (xlsm format) Now, this code will run automatically when you save the workbook. I imagined that you would open it, import a number of "Page 1" sheets and then want to make your totals. So, now you will have to save it first. The range D2:D4 (D2:D20 in my code) will be adjusted automatically.
If you don't like the automation, delete the Workbook_BeforeSave procedure entirely (or place an apostrophe at the beginning of each of its lines). You can run the SetPageRange procedure manually by placing the cursor anywhere in it and pressing F5. You can get it to be available for being run from Excel's worksheet interface by changing the attribute Private to Public.
The code will create a named range named "Pages" and you will need to change your formula to point to the named range (the size and content of which the code manipulates) instead of the present "D2:D4". The revised formula is included in the code's comments above.

How to use Countifs formula in VBA?

I am working on a workbook where there are 8 worksheets.
Names of worksheets:
[Hierarchy, wins, outlook, pcv, misses, losses, backdate, login].
In "Hierarchy" worksheet I want to apply the formula in a column B, up to the last value of that column B (which includes names of sales person). (I guess we will use a loop, I'm not sure which loop should I use.)
=COUNTIFS(wins!$AL:$AL,Hierarchy!$B4,wins!$P:$P,"Complete")
PS: I need help in above countif formula and loop (in VBA) to use that formula up to the last record in the column.
If you just need a result as opposed to filling formulas down the column in a worksheet, you could use one of these options:
Fast one - only using loops:
Sub countifs_in_vba()
Dim Result As Long
Dim i As Long
Dim cell As Range
Dim wsHierarchy As Worksheet
Dim wsWins As Worksheet
Set wsHierarchy = ThisWorkbook.Sheets("Hierarchy")
Set wsWins = ThisWorkbook.Sheets("wins")
For Each cell In Intersect(wsHierarchy.Range("B:B"), wsHierarchy.UsedRange)
For i = 1 To wsWins.Cells.SpecialCells(xlCellTypeLastCell).Row
If cell.Value = wsWins.Cells(i, "AL").Value And wsWins.Cells(i, "P").Value = "Complete" Then
Result = Result + 1
End If
Next
Next
MsgBox Result
End Sub
Slower one - employing Application.WorksheetFunction:
Sub countifs_in_vba2()
Dim Result As Long
Dim cell As Range
Dim wsHierarchy As Worksheet
Dim wsWins As Worksheet
Set wsHierarchy = ThisWorkbook.Sheets("Hierarchy")
Set wsWins = ThisWorkbook.Sheets("wins")
For Each cell In Intersect(wsHierarchy.Range("B:B"), wsHierarchy.UsedRange)
Result = Result + Application.WorksheetFunction.CountIfs(wsWins.Range("AL:AL"), cell.Value, wsWins.Range("P:P"), "Complete")
Next
MsgBox Result
End Sub

Write to two cells at same time excel vba

I need to write the same data into two different range of cells for a VBA application that I am writing. I could of course just loop through twice and write the data, but I was hoping to do it in one pass.
This is an example of what I am doing (lot of complexity removed).
Sub WriteData()
WriteOutDivision "Division1",10
WriteOutDivision "Division1",20
End Sub
Private Sub WriteOutDivision(ByVal divisionName, ByVal rowNumber)
Dim curSheet As Worksheet
Set curSheet = Sheets("Company Scorecard")
With curSheet.Cells(rowNumber, 1)
.value = divisionName
.Font.Bold = True
.InsertIndent 1
End With
End Sub
Is there something that I can do to write to both row 10 column 1 and row 20 column 1 at the same time?
You could define a non-contigous range and change the propeties of the range. For example:
Dim curSheet As Worksheet
Dim rngSpecial As Range
Set curSheet = Sheets("Company Scorecard")
Set rngSpecial = curSheet.Range("A1,A3")
rngSpecial.Value = "Whatever"
Will write "Whatever" in A1 and A3.
Could you just pass an array of row numbers instead of one rowNumber, then in your function just loop through each element in the array (I don't remember, I haven't programed in VBA for a while)? Then you could print it to as many rows as you want.

Resources