I ran into this problem and found several possible solutions depending on the need.
Save data to Hyperlink
You can store data in hyperlinks, for example, in the link itself or in the tooltip for the link. The advantage of this method is that the data is tied to the cell itself, and not to the address. This means that if, for example, someone sorts cells, followed by hidden data. You can also catch the HyperlinkClick event if you want, but none of these hyperlinks will go anywhere, so this probably doesn't matter.
Using ScreenTip
' Write hidden data to a cell Public Sub WriteData(ByVal Cell As Range, ByVal Data As String) Cell.Hyperlinks.Delete Cell.Hyperlinks.Add Cell, Address:="#", ScreenTip:=Data ' Set standard formatting With Cell.Font .Underline = xlUnderlineStyleNone .ColorIndex = xlAutomatic End With End Sub ' Read hidden data from a cell Public Function ReadData(ByVal Cell As Range) As String If Not CellContainsData(Cell) Then Exit Function ReadData = Cell.Hyperlinks(1).ScreenTip End Function Private Function CellContainsData(ByVal Cell As Range) As Boolean CellContainsData = Cell.Hyperlinks.Count > 0 End Function
Using Address
This probably has some restrictions on the look of the lines that you can save, as they should be somewhat valid links. For example, it should not contain spaces, but you, of course, can use a code (for example, \20
) to represent a space and decode it later.
Disclaimer : I'm not really quite sure what this does, I tried to find a way to create a valid link that has not gone away, and this is what I came up with. This violates Excel somewhat, since you can no longer edit the hyperlink using the Excel GUI, and clicking on it does not raise the FollowHyperlink
event. If you just set ?Data
as the address, Excel will clear it the next time you click.
' Write hidden data to a cell Public Sub WriteData(ByVal Cell As Range, ByVal Data As String) Cell.Hyperlinks.Delete Cell.Hyperlinks.Add Cell, Address:="//?" & Data, ScreenTip:="Nothing suspicious here." ' Set standard formatting With Cell.Font .Underline = xlUnderlineStyleNone .ColorIndex = xlAutomatic End With End Sub ' Read hidden data from a cell Public Function ReadData(ByVal Cell As Range) As String If Not CellContainsData(Cell) Then Exit Function Dim Data As String Data = Cell.Hyperlinks(1).Address ReadData = Right$(Data, Len(Data) - 3) End Function Private Function CellContainsData(ByVal Cell As Range) As Boolean If Cell.Hyperlinks.Count < 1 Then Exit Function Dim Data As String Data = Cell.Hyperlinks(1).Address ' Check that the cell has the correct prefix If Len$(Data) < 3 Then Exit Function If Left$(Data, 3) <> "\\?" Then Exit Function CellContainsData = True End Function
Save data to Validation
It is also possible to store data in a cell check. This, however, does not work if, for example, someone sorts the cells.
' Write hidden data to a cell Public Sub WriteData(ByVal Cell As Range, ByVal Data As String) With Cell.Validation ' Remove previous validation .Delete ' Write data on a specific format so you know it was you. .Add xlValidateCustom, Formula1:="""@" & Data & """" ' Hide it as well as possible .InCellDropdown = False .ShowInput = False .ShowError = False End With End Sub ' Read hidden data from a cell Public Function ReadData(ByVal Cell As Range) As String If Not CellContainsData(Cell) Then Exit Function Dim Data As String Data = Cell.Validation.Formula1 ReadData = Mid$(Data, 3, Len(Data) - 3) End Function Private Function CellContainsData(ByVal Cell As Range) As Boolean On Error GoTo InvalidValidation If Cell.Validation.Type <> xlValidateCustom Then Exit Function Dim Data As String Data = Cell.Validation.Formula1 ' Check that the data is on your specific format If Left$(Data, 2) <> """@" Then Exit Function If Right$(Data, 1) <> """" Then Exit Function CellContainsData = True InvalidValidation: Exit Function End Function