Hyperlink a newly added cell value from a closed workbook - excel

I can't seem to relate the discussion of this topic on this forum.
I have code here that uses hyperlink function but doesn't work.
I have a workbook opened at runtime docname that serves as a database.
And wbSource as current open workbook.
wbSource will send a cell value to docname and has to be converted into hyperlink.
path is the directory
Dest destination folder inside path
wb.Cells(BB + 2, 2) is the receiver. The file the hyperlink has to open is created almost the same time the link was created ( the line with the saveas command).
Set wb = Workbooks(DocName).Sheets("Sheet1")
Set wbs = Workbooks(wbSource).Sheets("MACRO")
Dim BB As Integer
wb.Cells(1, 1) = "=counta(B:B)"
BB = wb.Cells(1, 1)
wbNew = InputBox("Enter the 'Mold Number' or 'Part Name' here", "FileName")
ActiveWorkbook.SaveAs FileName:=Path & "\" & DesT & "\" & "RFQ Details_" & wbNew
Open wbNew For Output As #1
Close #1
wb.Cells(BB + 2, 2) = Hyperlink(Path & "\" & DesT & "\" & "RFQ Details_" & wbNew) 'THIS PART DOES NOT WORK!
Everything is working pretty fine except the last line.
I feel somethings really missing on that last part.

Tip: Whenever you are in doubt, if MS Excel lets you, record a macro and simply edit it.
I am assuming that you have valid values for BB, Path, Dest and DocName
Is this what you are trying?
Dim completePath As String
completePath = Path & "\" & DesT & "\" & "RFQ Details_" & wbNew
Set ws = Workbooks(DocName).Sheets("Sheet1")
Set rng = ws.Cells(BB + 2, 2)
rng.Hyperlinks.Add Anchor:=ws.Range(rng.Address), _
Address:=completePath, _
TextToDisplay:=completePath
Tested it with the below sample values and it works :)
Sub Sample()
Dim wb As Workbook
Dim ws As Worksheet
Dim BB As Long: BB = 1
Dim rng As Range
Dim Path As String, DesT As String, wbNew As String
Dim completePath As String
'~~> Sample Values
Path = "C:\Users\routs\Desktop"
DesT = "test"
wbNew = "Sample.xlsx"
DocName = ThisWorkbook.Name
Set wb = Workbooks(DocName)
Set ws = Workbooks(DocName).Sheets("Sheet1")
Set rng = ws.Cells(BB + 2, 2)
completePath = Path & "\" & DesT & "\" & "RFQ Details_" & wbNew
rng.Hyperlinks.Add Anchor:=ws.Range(rng.Address), _
Address:=completePath, _
TextToDisplay:=completePath
End Sub

I don't know why that did not work, but mine works, could you try this:
worksheets("Sheet1").hyperlinks.add _
anchor:=range("A1"), _
address:="https://9gag.com", _
texttodisplay :="9Gag"
Edited Code:
wb.Hyperlinks.Add _
anchor:=Cells(BB + 2, 2), _
Address:=(Path & "\" & DesT & "\" & "RFQ Details_" & wbNew), _
TextToDisplay:=Cells(BB + 2, 2)

Related

Change(some)Link(s) Name(s) of Active Workbook VBA

So, I renamed and moved some workbooks that are linked together and I need to update their xlExcelLinks on VBA, the thing is, I have a list of the references to update, but I can't figure out how to update only the ones I need and not every reference on the book.
The initial idea was to search for matching strings between a file name and the stored reference's path. Example data:
A2 Cell on Data.xlsx
Change to
I have this guide example code:
Sub Relink()
Dim previousFile, newFile, oldPath, newPath, Macro, altTab As String
'Macro stores the name of the file running the macro and altTab the name of the file to update
Dim ref as xlExcelLink 'Clearly not a type of data but I need something similar
Windows(Macro).activate
For I = 2 To 4
oldPath = Range("L"& I).Value
newPath = Range("M" & I).Value
previousFile = Range("N" & I).Value
newFile = Range("O" & I).Value
Windows(alTab).activate
'Somehow check for every reference avoiding itself
If ref.Address = oldPath & "\" & previousFile Then
ActiveWorkbook.ChangeLink Name:=oldPath & "\" & previousFile, _
NewName:=newPath & "\" & newFile, Type:=xlExcelLinks
End If
Next
End Sub
Note that on some files there could be only 1 update needed from 50ish references.
Try this code:
Sub UpdateLinks()
'Reference to your change list.
'ThisWorkbook is the file containing this code.
Dim ChangeList As Range
Set ChangeList = ThisWorkbook.Worksheets("Sheet2").Range("A2:D4")
'The workbook containing the links to change.
Dim wrkBk As Workbook
Set wrkBk = Workbooks("Test Timesheet.xlsx")
'If workbook isn't open use:
'Set wrkbk = workbooks.Open(<path to workbook>)
'Look at each link in the workbook.
'lnk must be Variant so it can be used in the For Each loop.
Dim lnk As Variant
For Each lnk In wrkBk.LinkSources
Dim OldPath As String
OldPath = Left(lnk, InStrRev(lnk, "\") - 1)
Dim OldFileName As String
OldFileName = Mid(lnk, InStrRev(lnk, "\") + 1, Len(lnk))
'Search for the existing path in first column of ChangeList.
Dim FoundLink As Range
Set FoundLink = ChangeList.Columns(1).Find(OldPath, , xlValues, xlWhole, xlByRows, xlNext)
'If it's not found, then continue to the next link.
'If it is found check that OldName also exists on that line, if it doesn't then continue searching.
If Not FoundLink Is Nothing Then
Dim firstAdd As String
firstAdd = FoundLink.Address
Do
If FoundLink.Offset(, 2) = OldFileName Then
'Found the link we're after so exit the loop.
Dim NewPath As String
NewPath = FoundLink.Offset(, 1)
Dim NewFileName As String
NewFileName = FoundLink.Offset(, 3)
Exit Do
Else
'Continue searching.
Set FoundLink = ChangeList.Columns(1).FindNext(FoundLink)
End If
Loop While firstAdd <> FoundLink.Address
'Make the change.
wrkBk.ChangeLink Name:=OldPath & Application.PathSeparator & OldFileName, _
NewName:=NewPath & Application.PathSeparator & NewFileName
End If
Next lnk
End Sub

ExcelVBA: SaveCopyAs won't allow edits to new Workbook

I'm attempting to create code that allows me to edit a workbook, create multiple copies, then edit those copies and save them. I'm hoping someone can talk me through the logic here because I've tried everything I can think of more than once.
Sub RemoveViolations()
Dim fBook As Workbook
Dim fBook2 As Workbook
LastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
fName = ActiveWorkbook.Name
fSheet = ActiveSheet.Name
fPath = ActiveWorkbook.Path
Set fBook = ActiveWorkbook
For Each c In ActiveSheet.Range("B4:B" & LastRow)
c = UCase(Trim(c.Value))
fName2 = Replace(fName, "swpaSumRPT-", "swpaSumRPT-" & c & "-")
fBook.ActiveSheet.Range("A3:L3").AutoFilter , field:=2, Criteria1:="<>" & c, Operator:=xlFilterValues
If fBook2 Is Nothing Then fBook.SaveCopyAs fPath & "\" & fName2
Set fBook2 = Application.Workbooks.Open(fPath & "\" & fName2)
MsgBox (ActiveWorkbook.Name)
Next c
End Sub
I'm not sure why I can't keep running the code from the original document after the new copy workbook is opened and activated. I've seen examples of others doing this and I THOUGHT I had properly followed the instructions. It appears that once the new workbook is open, the code stops running. I'm hoping you can help me understand.
I'm not toatlly sure what you want to do, but you can try the code below.
If you have more than one workbook open and you want to save all the workbooks, if you want to save all open workbooks, you can use the code below:
Sub SaveAllWorkbooks()
Dim wb As Workbook
For Each wb In Workbooks
wb.Save
Next wb
End Sub
Notice the Dim wb As Workbook. You should specifically reference all objects. Also, make sure everything is managed in the same instance of Excel that you are working with. As I know, a new instance of Excel can't 'see' a current instance of Excel. Check out the ink below when you have some free time.
https://trumpexcel.com/vba-workbook/
Try this adapted code, please:
Sub RemoveViolations()
Dim fBook As Workbook, fBook2 As Workbook, lastRow As Long, fName As String, strC As String
Dim c As Range, fSheet As String, fPath As String, fName2 As String, justName As String
lastRow = ActiveSheet.cells(ActiveSheet.Rows.count, "A").End(xlUp).row
fName = ActiveWorkbook.name
fSheet = ActiveSheet.name
fPath = ActiveWorkbook.Path
Set fBook = ActiveWorkbook
For Each c In ActiveSheet.Range("B4:B" & lastRow)
strC = UCase(Trim(c.Value))
'________________________________________________________________________
justName = Split(fName, ".")(0)
fName2 = Replace(justName, "swpaSumRPT-", "swpaSumRPT-" & strC & "-")
fName2 = fName2 & "." & Split(fName, ".")(1)
'________________________________________________________________________
fBook.ActiveSheet.Range("A3:L3").AutoFilter , field:=2, Criteria1:="<>" & c.value, Operator:=xlFilterValues
If fBook2 Is Nothing Then fBook.SaveCopyAs fPath & "\" & fName2
Set fBook2 = Application.Workbooks.Open(fPath & "\" & fName2)
MsgBox (ActiveWorkbook.name)
Set fBook2 = Nothing
Next c
End Sub
Take 2 steps, copy the files and then open them. This avoids changing the active workbook inside your loop.
Option Explicit
Sub RemoveViolations()
Dim fbook As Workbook, fbook2 As Workbook, ws As Worksheet
Dim c As Range, lastRow As Long
Dim fname As String, fname2 As String
Dim fpath As String, s As String
Dim copies As New Collection
Set fbook = ActiveWorkbook
Set ws = fbook.ActiveSheet
fname = fbook.Name
fpath = fbook.Path
lastRow = ws.Cells(Rows.Count, "B").End(xlUp).Row
' make copies and store name in a collection
For Each c In ws.Range("B4:B" & lastRow)
s = UCase(Trim(c.Value))
fname2 = Replace(fname, "swpaSumRPT-", "swpaSumRPT-" & s & "-")
'Debug.Print s, fname2
ws.Range("A3:L3").AutoFilter , field:=2, Criteria1:="<>" & c, Operator:=xlFilterValues
fbook.SaveCopyAs fpath & "\" & fname2
copies.Add fname2
Next c
ws.Range("A3:L3").AutoFilter ' remove
' open workbooks and delete visible rows
If MsgBox(copies.Count & " copies made. Do you want to open/edit them all ?", vbYesNo, "Confirm Open") = vbYes Then
Dim obj, rng As Range
For Each obj In copies
Set fbook2 = Application.Workbooks.Open(fpath & "\" & obj)
' avoid header 3 rows
Set rng = fbook2.ActiveSheet.UsedRange.Offset(3)
' delete visible rows
rng.SpecialCells(xlCellTypeVisible).EntireRow.Delete
fbook2.ActiveSheet.Range("A3:L3").AutoFilter ' remove filter
Next
End If
End Sub

Loop to save worksheet in new workbook

I want to run through a specific sheet (from & to) save those ws as a new file in a folder, if the folder doesn't exist then create.
I'm able to do it to one sheet.
ActiveSheet.Next.Select
If Range("F3").Value = "" Then
Windows("Import OT.xlsm").Activate
Sheets("Cash").Select
Dim filename101 As String
Dim path101 As String
Application.DisplayAlerts = False
path101 = Environ("UserProfile") & "\Dropbox\A271\5 Oppgjor\" & 2020 & "\"
filename101 = Range("B1").Value & ".xlsx"
ActiveWorkbook.SaveAs path101 & Range("A2") & "\" & Range("A1") & " " & filename101,xlOpenXMLWorkbook
Application.DisplayAlerts = True
Else
Cells.Select
Range("F3").Activate
Selection.Copy
Workbooks.Add
ActiveSheet.Paste
Dim Path1 As String
Dim fpathname1 As String
Path1 = Environ("UserProfile") & "\Dropbox\A271\4 Lonnslipper\"
fpathname1 = Path1 & Range("F3") & "\" & Range("F2") & " " & Range("B3") & ".xlsx"
path01 = Environ("UserProfile") & "\Dropbox\A271\4 Lonnslipper\" & Range("F3")
Dim path001 As String
Dim Folder As String
Folder = Dir(path01, vbDirectory)
If Folder = vbNullString Then
VBA.FileSystem.MkDir (path01)
ActiveWorkbook.SaveAs filename:=fpathname1, FileFormat:=51
ActiveWorkbook.Close
Sheets("Cash").Select
Else
ActiveWorkbook.SaveAs filename:=fpathname1, FileFormat:=51
ActiveWorkbook.Close
Sheets("Cash").Select
End If
End If
End Sub
I want this as a loop is because I have a few tens of sheets. For it to work I think I need to write it specific time, but with loop I learned I don't need to do that.
Excel file sheet
https://onedrive.live.com/view.aspx?resid=AF6FF2618C09AC74!29027&ithint=file%2cxlsx&authkey=!AHcJjYCu8D0NTNY
According to your comment where you wrote the steps:
Read the comments
Try to run the code using F8 key and see where you need to change it.
As you're learning, please note to first write the steps in plain English Norsk and then develop your code.
See how I just followed your steps with readable code.
Code:
Public Sub GenerateCustomersFiles()
' 1) Active sheet (oppgjør 1-20)
Dim targetSheet As Worksheet
For Each targetSheet In ThisWorkbook.Sheets
' Check only sheets with string in name
If InStr(targetSheet.Name, "Oppgjør") > 0 Then
' 2) look if value in F3 is empty
If targetSheet.Range("F3").Value = vbNullString Then
' 3) if it is, do select "cash" sheet and save this file (its name and path are given above what it should be named)
Dim fileName As String
Dim filePath As String
Dim folderPath As String
folderPath = Environ("UserProfile") & "\Dropbox\A271\5 Oppgjor\" & 2020 & "\"
fileName = targetSheet.Range("B1").Value & ".xlsx"
filePath = folderPath & targetSheet.Range("A2") & "\" & targetSheet.Range("A1") & " " & fileName
ThisWorkbook.Worksheets("Cash").Select
ThisWorkbook.SaveAs filePath, xlOpenXMLWorkbook
Else
' 4) if it doesn't, do open selected sheet to a new workbook and save that in clients name folder (folder and path given above in code section)
folderPath = Environ("UserProfile") & "\Dropbox\A271\4 Lonnslipper\" & targetSheet.Range("F3")
fileName = targetSheet.Range("F2") & " " & targetSheet.Range("B3") & ".xlsx"
filePath = folderPath & "\" & fileName
' 5) check if clients folder exist or not for the file to be saved in.
' if folder doesnt exist,
' create new and save file there.
CreateFoldersInPath folderPath
' if folder exist just save the file there
Dim targetWorkbook As Workbook
Set targetWorkbook = Workbooks.Add
targetSheet.Copy before:=targetWorkbook.Sheets(1)
targetWorkbook.SaveAs filePath, 51
targetWorkbook.Close
End If
End If
Next targetSheet
End Sub
' Credits: https://stackoverflow.com/a/31034201/1521579
Private Sub CreateFoldersInPath(ByVal targetFolderPath As String)
Dim strBuildPath As String
Dim varFolder As Variant
If Right(targetFolderPath, 1) = "\" Then targetFolderPath = Left(targetFolderPath, Len(targetFolderPath) - 1)
For Each varFolder In Split(targetFolderPath, "\")
If Len(strBuildPath) = 0 Then
strBuildPath = varFolder & "\"
Else
strBuildPath = strBuildPath & varFolder & "\"
End If
If Len(Dir(strBuildPath, vbDirectory)) = 0 Then MkDir strBuildPath
Next varFolder
'The full folder path has been created regardless of nested subdirectories
'Continue with your code here
End Sub
Let me know how it goes

Retrieve last value in a row of a specific column of multiple closed workbooks without opening

I have a list of files in a worksheet, that are files in a subfolder of the current directory.
I need to retrieve the value of a specific cell (can change), in a specific sheet (constant).
Of 10 files that are in the subfolder and which all have a sheet called "resumen", I want to get the value of the last row in column G.
So far I have this
Sub read_data_from_file_WO_openning()
Dim outputs_address As String
Dim FolderName As String, wbName As String, cValue As Variant
outputs_address = Sheets("lista_macro").Range("G2").Value
ruta_csv_output = ActiveWorkbook.Path & outputs_address
FolderName = ruta_csv_output
'select files to review
For Each file_analysis In Sheets("archivos_en_outputs").Range("I2", Range("I2").End(xlDown))
wbName = file_analysis.Value
cValue = GetInfoFromClosedFile2(FolderName, wbName, "resumen", "G1")
MsgBox (file_analysis & cValue) 'to see the values
Next file_analysis
End Sub
Private Function GetInfoFromClosedFile2(ByVal wbPath As String, _
wbName As String, wsName As String, cellRef As String) As Variant
Dim arg As String
If Right(wbPath, 1) <> "\" Then wbPath = wbPath & "\"
arg = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
GetInfoFromClosedFile2 = ExecuteExcel4Macro(arg)
End Function
In range I2 to down I have my list of files.
The problem is that my "G1" only retrieves data of cell G1 of all files, and I need the last row of column G for each file.
Sometimes these files have 7 rows, others have 15. The number of rows can change but always is at least 2.
I know the problem is in cell reference, but I don't know how to change this to accomplish what I have said.
Assuming that there are no blank spaces in Column G, you can use ExecuteExcel4Macro with the WorksheetFunction CountA to find the last row.
Function getLastValueInColumnG(ByVal wbPath As String, wbName As String, wsName As String) As Variant
Dim count As Long
Dim Address As String
Address = getExternalR1C1Address(wbPath, wbName, wsName, "G:G")
count = ExecuteExcel4Macro("CountA(" & Address & ")")
Address = getExternalR1C1Address(wbPath, wbName, wsName, "G" & count)
getLastValueInColumnG = ExecuteExcel4Macro(Address)
End Function
Function getExternalR1C1Address(ByVal wbPath As String, wbName As String, wsName As String, cellRef As String) As String
If Right(wbPath, 1) <> "\" Then wbPath = wbPath & "\"
getExternalR1C1Address = "'" & wbPath & "[" & wbName & "]" & wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
End Function
Another approach assuming you have limited number of rows in your output files (<1000 ?)
Option Explicit
Sub find_in_closed_files()
Application.ScreenUpdating = False
Dim Fch As Range
Dim Wb1 As Workbook: Set Wb1 = ActiveWorkbook
Dim Fld As String: Fld = Wb1.Path & Sheets("lista_macro").Range("G2").Value
If Not Right(Fld, 1) = "\" Then Fld = Fld & "\"
Dim Ws1 As Worksheet: Set Ws1 = Wb1.Sheets(1)
Dim Ws2 As Worksheet: Set Ws2 = Wb1.Sheets("tmp pull") 'This is a temp draft sheet to pull the data that you'll need to create
For Each Fch In Ws1.Range("I2", Ws1.Range("I2").End(xlDown))
Ws2.Cells.Clear
Ws2.Range("G1:G999").FormulaR1C1 = "=IF('" & Fld & "[" & Fch.Value & "]resumen'!RC<>"""",'" & Fld & "[" & Fch.Value & "]resumen'!RC,"""")"
Ws2.Range("G1:G999").Value2 = Ws2.Range("G1:G999").Value2
MsgBox Ws2.Range("G9999").End(xlUp).Value
Next Fch
Application.ScreenUpdating = True
End Sub
This leaves a formula in column G that will track the last text, number or date in column G of the resumen worksheet within the closed external workbooks.
Sub xlsxLastG()
Dim i As Long, f As String
With Worksheets("archivos_en_outputs")
For i = 2 To .Cells(.Rows.Count, "I").End(xlUp).Row
'conform C:\Users\public\AppData\Documents\test.xlsb
' to 'C:\Users\public\AppData\Documents\[test.xlsb]resumen'!G:G
f = .Cells(i, "I").Value
f = Left(f, InStrRev(f, Chr(92))) & Chr(91) & Right(f, Len(f) - InStrRev(f, Chr(92)))
f = Chr(39) & f & Chr(93) & "resumen'!G:G"
.Cells(i, "G").Formula = _
"=index(" & f & ", max(iferror(match(1e99, " & f & "), 0), iferror(match(""zzz"", " & f & "), 0)))"
Next i
End With
End Sub
#N/A errors would typically mean column G was blank; #REF! errors would indicate not existing workbook or no resumen worksheet within the referenced workbook.

How to Create Folder, File, and Save File in Folder

EDIT: Wasn't clear enough with my question
Sub NewWB2()
Dim wb As Workbook
Dim POname As String
Dim lrow As Long
Dim NewfolderPath As String
lrow = Cells(Rows.Count, 3).End(xlUp).Row
POname = Worksheets("Sheet1").Cells(lrow, 10).Value 'name I want for both the folder and the document
MkDir "C:\Users\First.Last\Desktop" & "\" & POname 'creates the folder in the path I want
NewfolderPath = "C:\Users\First.Last\Desktop\" & POname ' variable to define that path
Set wb = Workbooks.Add("C:\Users\First.Last\Documents\Custom Office Templates\PO Template.xltm") ' creates from template
ActiveWorkbook.SaveAs Filename:=POName 'Saves file as variable "POname"
End Sub
Everything here works. All I need to do is to add a line of code that will save the new workbook in the folder I've created. I can't find how to do this and don't know how to add this in.
Try with this, guess you are missing your Filename:
ActiveWorkbook.SaveAS Filename:=NewfolderPath & "\" & POname & "\Filename"
if you are using a Variable for your filename try:
ActiveWorkbook.SaveAS Filename:=NewfolderPath & "\" & POname & "\" & Filename
Can you provide a string example of POname that you are using?
I think you missed a '\' in NewfolderPath:
Try:
Sub NewWB2()
Dim wb As Workbook
Dim POname As String
Dim lrow As Long
Dim NewfolderPath As String
lrow = Cells(Rows.Count, 3).End(xlUp).Row 'finds the last row
POname = Worksheets("Sheet1").Cells(lrow, 10).Value 'name of Folder and File
NewfolderPath = "C:\destinationfoldername\" & POname
MkDir NewfolderPath 'creates the new folder with the name defined above
Set wb = Workbooks.Add("C:\folderwithtemplate\Template.xltm") 'creates new wb from template
ActiveWorkbook.SaveAs NewfolderPath & "\" & POname
End Sub

Resources