Changing Value of Combo Box to another Value in VB - string

I am trying to change the value of a combo box value "Black Shredded - 7.90" to just show "Black Shredded" when it is selected
Dim intIndex As Integer
Dim strString1 As String
Dim strString2 As String
strString1 = cboProduct.SelectedItem
intIndex = strString1.IndexOf(" ")
strString2 = strString1.Remove(intIndex + 9)
If cboProduct.SelectedIndex = 0 Then
cboProduct.Text = strString2
End If
I went through the values and they show as they should but it isn't changing the combobox value what could I be doing wrong?

If you have just added Strings to the ComboBox in the first place then you need to replace the existing item with the new value. This:
cboProduct.Text = strString2
should be this:
cboProduct.Items(cboProduct.SelectedIndex) = strString2
You can just use 0 rather than cboProduct.SelectedIndex, given that you have already confirmed that that is the index at that point.
Setting the Text property doesn't affect the items at all. If DropDownStyle is set to DropDown then the specified text will be displayed but no item will be selected. If DropDownStyle is set to DropDownList then the item with that text will be selected, if one exists. Either way, no item is added or changed.

Related

How to use String value as a dot operation in VBA? it is possible?

Sub getTrailInfo()
Dim attr As Variant
Dim attrTB As String
attrNames = Split("trailName,trailType,aSideSite,zSideSite,status", ",")
Dim trailForm As New formTrailInfo
For Each attr In attrNames
attrTB = attr + "TB"
trailForm.attrTB = attr
Next attr
trailForm.Show
End Sub
When I run the above code it gives a compilor error: Method or Data not found at line trailForm.attrTB = attr
I have required variables in attrNames String array. I need to put values of these variables in corosponding textboxes in a userForm. The name of Text Box in this userForm is attrNameTB. For example Text box for trailName is trailNameTB.
You cannot use VBA like that.
When you start your code, the compiler will first compile the code and check that you want to access a property named attrTB of your form. This doesn't exist and you will get the error you mentioned.
The compiler cannot wait until your variable attrTB has an actual value and then guess that you don't want a property with that name, but use the content of that variable as property name.
However, every form has a collection of all it's controls (button, edit boxes, combo boxes, labels...), and you can access the members of a collection either by index or by name. As you have the name of the control in attrTB, you could simply write
trailForm.Controls(attrTB).Text = attr

Clear ComboBox Containig an Array VBA and Repopulate with Column Index

I have a sigle column ComboBox that I have populated with a dynamic array; however, I'd like the code to replace the value of the combo box with respective column from my ListBox.
'Prepares the Active Escorts list box.
ivb = 0
i = 0
With frmEntry
.listboxActiveEscorts.Clear
.listboxActiveEscorts.ColumnHeads = False
.listboxActiveEscorts.ColumnCount = "15"
.listboxActiveEscorts.ColumnWidths = "0,100,100,0,0,100,100,0,0,0,0,0,100,100,80"
i = 0
'Badge # combobox properties
ReDim vbArray(0 To vbArrayCount - 1)
For i = 0 To vbArrayCount - 1
ivb = ivb + 1
vbArray(ivb - 1) = loVisBadge.Range.Cells(i + 2, 1).Value
Next i
.cbxVisitorBadgeNumber.List = vbArray
End With
This population of the ComboBox executes beautifully, in my belief, but if you see a better way to implement the dynamic list, I'm all ears.
I have a button that I will use to reset the form, which also works for the most part. When an item is selected from the list, I am able to clear all controls except for the ComboxBox containing the array of values. I will be adding two additional arrays to each of the other ComboBoxes on the form, and I imagine I am going to have the same problem: "Could not set the value property. Invalid property value"
This is the code assigned to click event of the ListBox:
Private Sub listboxActiveEscorts_Click()
With frmEntry
.cbxEscortSelectName.Value = .listboxActiveEscorts.Column(1) + " " + .listboxActiveEscorts.Column(2)
.txtCredential.Value = .listboxActiveEscorts.Column(4)
.txtEscortCompany.Value = .listboxActiveEscorts.Column(3)
.cbxVisitorName.Value = .listboxActiveEscorts.Column(5) + " " + .listboxActiveEscorts.Column(6)
.txtVECompany.Value = .listboxActiveEscorts.Column(7)
.txtVEDOB.Value = .listboxActiveEscorts.Column(8)
.txtVEIdentification.Value = .listboxActiveEscorts.Column(9)
.txtVEIDNumber.Value = .listboxActiveEscorts.Column(10)
.txtVEExpirationDate.Value = .listboxActiveEscorts.Column(11)
.txtVEStart.Value = .listboxActiveEscorts.Column(12)
.txtVEEnd.Value = .listboxActiveEscorts.Column(13)
'.cbxVisitorBadgeNumber.Value = ""
.cbxVisitorBadgeNumber = vbNullString
.cbxVisitorBadgeNumber.Value = .listboxActiveEscorts.Column(14)
End With
End Sub
What am I missing here. I tried to ReDim the array that assigned the values, but that didn't work. Is it a data type thing, perhaps?
In the picture below, you'll see the values populated in the controls, all except the visitor badge # (ComboBox which throws the error...I have commented out the line for illustration purposes, so you'll see the visitor badge # is blank).

Update an Excel style in VBA

My Excel macro reads the answers to a survey from a set of Excel files. The answers of a survey contain a score (from 1 to 4) and a description. The goal is to generate a a matrix. Each cell of the matrix has a color that represents the score. I would like the user to be able to modify the layout of these cell. To make it easy to the user, I created a template matrix and a button. The user should be able to modify the layout of the cells and on a click of a button, a set of styles (Score 1, Score 2,...) should be generated. Once the matrix is created, the Workbook should be to function without the survey files.
I have tried a couple of things:
Try 1
ThisWorkbook.Styles.Add "Score 1", BasedOn:=cell1
This gives errors. I don't fully understand when they occur, but one of the causes is when the user modifies the cell layout by selecting another style.
Try 2
ThisWorkbook.Styles("Score 1").Delete
ThisWorkbook.Styles.Add "Score 1", BasedOn:=cell1
This is not a good idea: all cells loose their styling when it is executed a second time.
Try 3: Current
Copy the most frequently used properties of the cells layout and copy them to the style. If this style is deleted by the user, it is recreated. This procedures is not ideal, since most style properties won't be covered.
Is there a way to update a cell style that is more general? I would like there to be as little room as possible to make the workbook in an inconsistent and non-functional state.
I sticked with try 3. Because it required a lot of code for all properties that seemed possible to be edited, and because of copying borders is tricky, I post the result.
'xR1_Template: the cell to base the style on
'nm_Style: the name of the style
Public Function Upsert_Style(xR1_Template As Excel.Range, nm_Style As String) As Excel.Style
Dim xStyle As Excel.Style
Set xStyle = Fn.TryGet(ThisWorkbook.Styles, nm_Style)
If Fn.IsNothing(xStyle) Then
Set xStyle = ThisWorkbook.Styles.Add(nm_Style)
End If
xStyle.Font.Color = xR1_Template.Font.Color
xStyle.Font.Bold = xR1_Template.Font.Bold
xStyle.Font.Name = xR1_Template.Font.Name
xStyle.Font.Italic = xR1_Template.Font.Italic
xStyle.Font.Size = xR1_Template.Font.Size
xStyle.Font.Strikethrough = xR1_Template.Font.Strikethrough
xStyle.Font.Subscript = xR1_Template.Font.Subscript
xStyle.Font.Superscript = xR1_Template.Font.Superscript
xStyle.Font.Underline = xR1_Template.Font.Underline
xStyle.Interior.Color = xR1_Template.Interior.Color
xStyle.Interior.Pattern = xR1_Template.Interior.Pattern
xStyle.Interior.PatternColor = xR1_Template.Interior.PatternColor
'NOTE: necessary to delete all borders first. There's no way to delete them one by one.
xStyle.Borders.LineStyle = xlNone
Dim iBorder As Long
For iBorder = 1 To xR1_Template.Borders.Count
Dim xBorder As Excel.Border
'NOTE: The Borders property claims to work with xlBordersIndex argument, but this is not true.
' Normal indexing is used.
Set xBorder = xR1_Template.Borders(iBorder)
'NOTE: "none-style" borders (=no border), should be skipped.
' Once they are retrieved using the Borders property, they are always visible.
' Setting them with xlLineStyle.xlLineStyleNone does not hide them.
If xBorder.LineStyle <> XlLineStyle.xlLineStyleNone Then
Dim xBorder_Style As Excel.Border
Set xBorder_Style = xStyle.Borders(iBorder)
xBorder_Style.Color = xBorder.Color
xBorder_Style.LineStyle = xBorder.LineStyle
xBorder_Style.Weight = xBorder.Weight
End If
Next iBorder
xStyle.AddIndent = xR1_Template.AddIndent
xStyle.FormulaHidden = xR1_Template.FormulaHidden
xStyle.HorizontalAlignment = xR1_Template.HorizontalAlignment
xStyle.IndentLevel = xR1_Template.IndentLevel
xStyle.NumberFormat = xR1_Template.NumberFormat
xStyle.NumberFormatLocal = xR1_Template.NumberFormatLocal
xStyle.Orientation = xR1_Template.Orientation
xStyle.ShrinkToFit = xR1_Template.ShrinkToFit
xStyle.VerticalAlignment = xR1_Template.VerticalAlignment
xStyle.WrapText = xR1_Template.WrapText
xStyle.IndentLevel = xR1_Template.IndentLevel
Set Upsert_Style = xStyle
End Function

Matlab - Display trailing edge of a long strings in a listbox by hovering the mouse over the string

I have a Matlab listbox on which some strings are very long. I do not want to make listbox too wide just only because of these few long strings.
Is there anyway to display trailing edge of these long strings in my listbox by simply hovering the mouse over those strings without using scroll pane?
Perhaps, you can set the TooltipString property of your listbox. This is what is displayed when you hover the cursor on some object. It will not be a nice or user friendly but is better than nothing.
%Create a listbox
myListbox = uicontrol('Style','listbox');
set(myListbox,'TooltipString','','Callback',#listboxCB);
%Callback function called each time the listbox value is changed
%It should also be called whenever the 'String' property is updated
function listboxCB(obj,evt)
%Get the value
v=get(obj,'Value');
if isempty(v)
set(myListbox,'TooltipString','');
return;
end
%Get the string corresponding to that line
str = get(obj,'String');
str = str{v(1)}; %Show the first one (if 'multiselect' = 'on')
set(myListbox,'TooltipString',str);
end
There may be some clever way by interacting directly with the underlying Java objects.
See Jan's answer using Java objects. Worked great.
% Prepare the Matlab listbox uicontrol
hFig = figure;
listItems = {'apple','orange','banana','lemon','cherry','pear','melon'};
hListbox = uicontrol(hFig, 'style','listbox', 'pos',[20,20,60,60], 'string',listItems);
% Get the listbox's underlying Java control
jScrollPane = findjobj(hListbox);
% We got the scrollpane container - get its actual contained listbox control
jListbox = jScrollPane.getViewport.getComponent(0);
% Convert to a callback-able reference handle
jListbox = handle(jListbox, 'CallbackProperties');
% Set the mouse-movement event callback
set(jListbox, 'MouseMovedCallback', {#mouseMovedCallback,hListbox});
% Mouse-movement callback
function mouseMovedCallback(jListbox, jEventData, hListbox)
% Get the currently-hovered list-item
mousePos = java.awt.Point(jEventData.getX, jEventData.getY);
hoverIndex = jListbox.locationToIndex(mousePos) + 1;
listValues = get(hListbox,'string');
hoverValue = listValues{hoverIndex};
% Modify the tooltip based on the hovered item
msgStr = sprintf('<html>item #%d: <b>%s</b></html>', hoverIndex, hoverValue);
set(hListbox, 'Tooltip',msgStr);
end % mouseMovedCallback
https://www.mathworks.com/matlabcentral/answers/436048-display-trailing-edge-of-a-long-strings-of-a-listbox-by-hovering-the-mouse-over-the-string#answer_352806

Using multiple values field in Lotus Notes

I am trying to write a logging system for a form in Lotus Notes but I am at the part where I am not sure how I can append the information about the fields that are changed in the log fields. There are 3 fields that I use Log_Date (date), Log_User and Log_Actions (Text, allow multiple values).
I thought if I add comma to the log field it will create a new line when displaying the form but I am still getting a type mismatch on the case 2 line.
How can I append the new values to the log fields?
Sub Querysave(Source As Notesuidocument, Continue As Variant)
' Compare the values in the form after it is saved with its original values when the document is not a new document.
Dim doc As NotesDocument
Set doc = Source.Document
Dim session As New NotesSession
Dim user As String
user = session.CommonUserName
If newDoc Then
doc.Log_Date = Now()
doc.Log_User = user
doc.Log_Actions = "New document created."
Else
' Load fields value to the array
lastValues(0) = doc.QCR_No(0)
lastValues(1) = doc.QCR_Mobile_Item_No(0)
lastValues(2) = doc.QCR_Qty(0)
' Compared each value in the array to see if there is any difference
Dim i As Integer
For i = 0 To 2
If lastValues(i) <> originalValues(i) Then
Select Case i
Case 2 : doc.Log_Actions = doc.Log_Actions & "," & "Field QCR_Qty is changed"
End Select
End If
Next
End If
End Sub
doc.Log_Actions returns the notesitem. To access the value you need to use doc.Log_Actions(0)
In LotusScript back-end classes (e.g. NotesDocument, NotesItem), a multi-valued field is represented by an array with one value per element of the array. For setting the value of a field, doc.Log_Actions is shorthand (they call it 'extended syntax' in the Domino Designer help) for assigning the first (i.e., zero subscript) element of the array, but that does not work for getting the value. To get the first value, you have to use doc.Log_Actions(0). To get or set the second value, you have to use doc.Log_Actions(1).
So, your Case 2 code could look like this:
doc.Log_Actions(1) = "Field QCR_Qty is changed"
My guess, however, is that you really want to be able to continually append to the end of the list of values each time this code runs. You are also going to want your code to be robust and not blow up on you if (for any reason!) the Log_Actions item does not exist in the document. For that, you are going to want to do this:
dim actionsItem as NotesItem
if doc.hasItem("Log_Actions") then
set actionsItem = doc.getFirstItem("Log_Actions")
call actionsItem.AppendToTextList("Field QCR_Qty is changed")
end if
Or,
If (Not doc.HasItem("LogActions")) Then
doc.LogActions = "Field QCR_Qty is changed"
Else
doc.LogActions = ArrayAppend(doc.LogActions,"Field QCR_Qty is changed")
End If
This is equivalent to the NotesItem method by rhsatrhs, which you use is matter of preference.

Resources