This solution is UDF based, so that triggering cells and storage cells can be controlled from the worksheet, rather than hardcoded into the VB.
Clicking on a cell cannot be distinguished from tabbing into it, so I used a double click instead.
In the OP, you mentioned Sheet1!$A$1 being the source and the user's entry being stored in Sheet2!$B$2.
The user's experience will be:
Double click on the trigger cell (Sheet1!$A$1).
Type "text" into the dialog box that appears.
Press OK.
Go to Sheet2 and see "Text" in B2.
Go back to Sheet1, hover over A1 and see the cell's comment, "text".
The first UDF is UserEnterComment (ValueToShow, (optional) inputPrompt, (optional) inputTitle)
If user double-clicks on a cell with a formula that uses the function UserEnterComment , a dialog box will appear.
The user's entry will become the text of that cell's comment.
The value returned by UserEnterComment is the value of the first argument.
The inputPrompt and inputTitle arguments are passed to the dialog box.
In the OP example, Sheet1!$A$1 would hold the formula
=SourceOfComment("X", "Question Here")
The three arguments of SourceOfComment are:
ValueToShow - the value that the cell will show
inputPrompt - (optional) the prompt for the dialog box (when double clicked) (default "Enter text.").
inputTitle - (optional) the title for the dialog box (default "Text Input")
Put this in a normal module:
Code:
Function UserInputComment(ValueToShow As Variant, _
Optional inputPrompt As String, Optional inputTitle As String) As Variant
On Error Resume Next
With Application.Caller
.AddComment
With .Validation
.Delete
.Add Type:=xlValidateCustom, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=true"
.inputTitle = inputTitle
.InputMessage = inputPrompt
.ShowInput = False
.ShowError = False
End With
End With
On Error GoTo 0
UserInputComment = ValueToShow
End Function
and this in the ThisWorkbook code module:
Code:
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Dim uiComment As String, ioPrompt As String, ioTitle As String
With Target
If UCase(.Formula) Like "*USERINPUTCOMMENT(*" Then
Cancel = True
ioPrompt = .Validation.InputMessage
ioTitle = .Validation.inputTitle
'uiComment = Application.InputBox(prompt:=ioPrompt, Default:=.Comment.Text, Title:=ioTitle, Type:=2)
uiComment = UserForm1.GetInput(strPrompt:=ioPrompt, strDefault:=.Comment.Text, strTitle:=ioTitle)
If uiComment <> "False" Then
.Comment.Text Text:=uiComment
.Formula = .Formula
End If
End If
End With
End Sub
Notice that the dialog could be Application.InputBox, but it looks you like you need (and have?) a userform to handle multi-line text entry.
As is, the code invokes UserForm1 (see next post).
The commenting out could be reversed if you prefer an Application.InputBox.
The second UDF is CommentFromCell(sourceRange).
CommentFromCell returns the text of the comment in sourceRange's upper left cell.
For the OP example, Sheet2 B2 would hold the formula
=CommentFromCell(Sheet1!$A$1)