I am trying to create a workaround for the Data Validation Input Message, since my input message is more than 255 chars.
I have tried http://contextures.com/xlDataVal12.html but the text box is fixed. I would need the text box or label to move with the selected cell.
On the image below, you can see the issue. We cannot display the whole message within the input box.
1 http://img5013.photobox.co.uk/42779160c8143d2fcab8c396d411e8b621181c1be9f1a01fb62e272d26debaf4b53f7657.jpg
Using the Contextures code, you need to set the .Top and .Left properties of the shape to the same properties of a cell. Here's a rewrite of that code that moves the textbox near the cell.
' Developed by Contextures Inc.
' www.contextures.com
' modified by Dick Kusleika 7/21/2015
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim sTitle As String
Dim sMsg As String
Dim sMsgAdd As String
Dim tbxTemp As Shape
Dim lDVType As Long
Dim lRowMsg As Long
Dim ws As Worksheet
Application.EnableEvents = False
Set ws = Target.Parent
Set tbxTemp = ws.Shapes("txtInputMsg")
On Error Resume Next
lDVType = 0
lDVType = Target.Validation.Type
On Error GoTo errHandler
If lDVType = 0 Then
tbxTemp.TextFrame.Characters.Text = vbNullString
tbxTemp.Visible = msoFalse
Else
If Len(Target.Validation.InputTitle) > 0 Or Len(Target.Validation.InputMessage) > 0 Then
sTitle = Target.Validation.InputTitle & vbLf
On Error Resume Next
lRowMsg = 0
lRowMsg = Application.WorksheetFunction.Match(Target.Validation.InputTitle, Sheets("MsgText").Columns(1), 0)
If lRowMsg > 0 Then
sMsgAdd = Me.Parent.Sheets("MsgText").Cells(lRowMsg, 2).Value
End If
On Error GoTo errHandler
sMsg = Target.Validation.InputMessage
With tbxTemp.TextFrame
.Characters.Text = sTitle & sMsg & vbLf & sMsgAdd
.Characters.Font.Bold = False
.Characters(1, Len(sTitle)).Font.Bold = True
End With
tbxTemp.Top = Target.Offset(1, 1).Top
tbxTemp.Left = Target.Offset(1, 1).Left
tbxTemp.Visible = msoTrue
tbxTemp.ZOrder msoBringToFront
Else
tbxTemp.TextFrame.Characters.Text = vbNullString
tbxTemp.Visible = msoFalse
End If
End If
errHandler:
Application.EnableEvents = True
End Sub
Related
I'm trying to insert pictures into Excel files from entering the serial number in a cell.
I get a syntax error where it is trying to insert the pictures. Specifically where it says .Shapes.AddPicture.
Sub picture_insert()
Dim picBild As Picture
Dim blnAvailable As Boolean
Dim link As String
Dim Pattern As String
Dim Serial As String
Dim t As String
Dim P1 As String
Dim P2 As String
link = "\\chimera\home\hillerbr\My Documents\Index project\"
Pattern = Range("A14")
Serial = Range("B14")
t = ".jpg"
P1 = Range("C14")
P2 = Range("D14")
With Worksheets("Data Breakdown")
For Each picBild In .Pictures
If picBild.Name = "280.1" Then
'The picture already exists
blnVorhanden = True
Exit For
End If
Next picBild
'only execute if picture does not yet exist
If blnVorhanden = False Then
With .Shapes.AddPicture Filename := link & Pattern & Serial & P1 & t
.Name = Range("C14")
.ShapeRange.LockAspectRatio = msoFalse
.Width = 450
.Height = 500
.Left = Worksheets("Data Breakdown").Range("A10").Left
.Top = Worksheets("Data Breakdown").Range("G20").Top
End With
With .Shapes.AddPicture Filename := link & Pattern & Serial & P1 & t
.Name = Range("D14")
.ShapeRange.LockAspectRatio = msoFalse
.Width = 450
.Height = 500
.Left = Worksheets("Data Breakdown").Range("E10").Left
.Top = Worksheets("Data Breakdown").Range("G20").Top
End With
End If
End With
End Sub
Sub Image_Remove()
Dim picBild As Picture
With Worksheets("Data Breakdown")
For Each picBild In .Pictures
If picBild.Name = Range("C14") Then
picBild.Delete
Exit For
End If
Next picBild
For Each picBild In .Pictures
If picBild.Name = Range("D14") Then
picBild.Delete
Exit For
End If
Next picBild
End With
End Sub
Providing your variables point to a valid image I found the below code works.
Sub Test()
Dim sht As Worksheet
Set sht = Worksheets("Data Breakdown")
With sht
With .Shapes.AddPicture(Filename:=link & Pattern & Serial & P1 & t, _
LinkToFile:=True, SaveWithDocument:=True, _
Left:=.Range("A10").Left, Top:=.Range("G20").Top, Width:=450, Height:=500)
.Name = "ABC"
.LockAspectRatio = True
End With
End With
End Sub
The Help page for AddPicture says there's 7 required parameters.
I am trying to create a VBA that allows autocomplete when typing in a data validation cell. I have obtained code from the following question What VBA event allows to capture click value of ActiveX combobox?.
Problem is that when I use the below code from that question and have it run off my name range, which is a list of 200 paragraphs that it is searching within, it crashes me out of excel immediately and I am not sure why. Is there an issue with the code or is searching within 200 paragraphs in 200 separate cells just not viable with VBA?
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim xArr
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("TempCombo")
With xCombox
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
If Target.Validation.Type = 3 Then
Target.Validation.InCellDropdown = False
'Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
If .ListFillRange = "" Then
xArr = Split(xStr, Application.International(xlListSeparator))
Me.TempCombo.List = xArr
End If
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.TempCombo.DropDown
End If
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 9 'tab
Application.ActiveCell.Offset(0, 1).Activate
Case 13 'enter
Application.ActiveCell.Offset(1, 0).Activate
End Select
End Sub
Private Sub TempCombo_Change()
If Me.TempCombo = "" Then Exit Sub
ActiveSheet.OLEObjects(1).ListFillRange = ""
ActiveSheet.OLEObjects("TempCombo").Object.Clear
ThisWorkbook.ActiveSheet.OLEObjects("TempCombo").Activate
With Me.TempCombo
If Not .Visible Then Exit Sub
.Visible = False 'to refresh the drop down
.Visible = True
.Activate
'Dump the range into a 2D array
Dim Arr2D As Variant
Arr2D = [QoE].Value
'Declare and resize the 1D array
Dim Arr1D As Variant
ReDim Arr1D(1 To UBound(Arr2D, 1))
'Convert 2D to 1D
Dim i As Integer
For i = 1 To UBound(Arr2D, 1)
Arr1D(i) = Arr2D(i, 1)
Next
Dim itm As Variant 'itm is for iterate purpose
Dim ShortItemList() As Variant 'ShortItemList() is a variable which stores only filtered items
i = -1
For Each itm In Arr1D
If InStr(1, itm, .Value, vbTextCompare) > 0 Or .Value = "" Then
Debug.Print itm
i = i + 1
ReDim Preserve ShortItemList(i)
ShortItemList(i) = itm
End If
Next itm
.DropDown
End With
On Error Resume Next 'if we filter too much, there will be no items on ShortItemList
ThisWorkbook.ActiveSheet.OLEObjects("TempCombo").Object.List = ShortItemList
End Sub
You don't use .DropDown. It crash Excel when ComboBox hide or delete
After choosing item from ActiveX combobox by mouse click I would like the combobox to be closed and the item to be chosen.
Here is an example.
I have tried TempCombo_Click event but it is fired AFTER the TempCombo_Change event. And when I select item by click, my search string passed to TempCombo_Change event is empty. So I need something to preserve item selection in TempCombo_Change event.
I use modification of VBA code taken from Autocomplete suggestion in Excel data validation list again
Here is VBA exact code I use to generate the above example.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim xArr
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("TempCombo")
With xCombox
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
If Target.Validation.Type = 3 Then
Target.Validation.InCellDropdown = False
'Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
If .ListFillRange = "" Then
xArr = Split(xStr, Application.International(xlListSeparator))
Me.TempCombo.List = xArr
End If
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.TempCombo.DropDown
End If
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 9 'tab
Application.ActiveCell.Offset(0, 1).Activate
Case 13 'enter
Application.ActiveCell.Offset(1, 0).Activate
End Select
End Sub
Private Sub TempCombo_Change()
If Me.TempCombo = "" Then Exit Sub
ActiveSheet.OLEObjects(1).ListFillRange = ""
ActiveSheet.OLEObjects("TempCombo").Object.Clear
ThisWorkbook.ActiveSheet.OLEObjects("TempCombo").Activate
With Me.TempCombo
If Not .Visible Then Exit Sub
.Visible = False 'to refresh the drop down
.Visible = True
.Activate
'Dump the range into a 2D array
Dim Arr2D As Variant
Arr2D = [RangeItems].Value
'Declare and resize the 1D array
Dim Arr1D As Variant
ReDim Arr1D(1 To UBound(Arr2D, 1))
'Convert 2D to 1D
Dim i As Integer
For i = 1 To UBound(Arr2D, 1)
Arr1D(i) = Arr2D(i, 1)
Next
Dim itm As Variant 'itm is for iterate purpose
Dim ShortItemList() As Variant 'ShortItemList() is a variable which stores only filtered items
i = -1
For Each itm In Arr1D
If InStr(1, itm, .Value, vbTextCompare) > 0 Or .Value = "" Then
Debug.Print itm
i = i + 1
ReDim Preserve ShortItemList(i)
ShortItemList(i) = itm
End If
Next itm
.DropDown
End With
On Error Resume Next 'if we filter too much, there will be no items on ShortItemList
ThisWorkbook.ActiveSheet.OLEObjects("TempCombo").Object.List = ShortItemList
End Sub
This line in the TempCombo_Click event solved the problem:
ActiveCell.Value = ThisWorkbook.ActiveSheet.OLEObjects("TempCombo").Object.Value
is it possible to generate a combobox/dropdownlist inside a cell that is currently active? I tried this but nothing happened:
Programmatically add a drop down list to a specific cell
my client wants any cell that has been clicked from column A (except A1 because it serves as the Column header) to have dropdowns with list of items.
I also tried copying this and see if it runs but it always go to the On Error Resume Next
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
On Error GoTo errHandler
If Target.Count > 1 Then GoTo exitHandler
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = ""
End With
End If
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
'if the cell contains a data validation list
Application.EnableEvents = False
'get the data validation formula
str = Target.Validation.Formula1
str = Right(str, Len(str) - 1)
With cboTemp
'show the combobox with the list
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 15
.Height = Target.Height + 5
.ListFillRange = ws.Range(str).Address
.LinkedCell = Target.Address
End With
cboTemp.Activate
End If
exitHandler:
Application.ScreenUpdating = True
Application.EnableEvents = True
Exit Sub
errHandler:
Resume exitHandler
End Sub
I'm trying to use autofill drop-down list in Excel
The code which i used.I got it from here
http://www.contextures.com/DataValComboboxClick.zip
All the sudden it stopped working (worked for 2 months before)
Now i am getting 438 error
"Object does not support this property or method" in this line: .Value
= ""
The weird thing is that when i try to type the following in the immediate window: ?cbotemp.value, the promt shows me that cbotemp object does not have a Value property at all
Any help will be highly appreciated. I'm trying to work it out all night long and now it becomes desperate.
Here is the source code:
Option Explicit
' Developed by Contextures Inc.
' www.contextures.com
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
'Hide combo box and move to next cell on Enter and Tab
Select Case KeyCode
Case 9
ActiveCell.Offset(0, 1).Activate
Case 13
ActiveCell.Offset(1, 0).Activate
Case Else
'do nothing
End Select
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
Cancel = True
End If
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
With cboTemp
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
Application.EnableEvents = False
str = Target.Validation.Formula1
str = Right(str, Len(str) - 1)
With cboTemp
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 15
.Height = Target.Height + 5
.ListFillRange = ws.Range(str).Address
.LinkedCell = Target.Address
End With
cboTemp.Activate
'open the drop down list automatically
Me.TempCombo.DropDown
End If
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = "" 'here i get 438 error
End With
End If
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
The error is in this part of code:
...
Dim cboTemp As OLEObject
...
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = ""
End With
End If
Since cboTemp is of type OLEObject it really has not a property Value. But the On Error Resume Next should prevent this error from breaking the program.
If this is not (or not more) the case, then the setting in:
VBA Editor - Tools > Options > General > Error Trapping
is set to Break on all errors.
Default is Break on unhandled errors.
Set it back to default or simply do not set .Value="" at all. It is not necessary.