VB.net Autocomplete Textbox filter using mysql database as custom source - mysql

I'm Having a problem regarding to the autocomplete textbox. First I already made the autocomplete textbox work with mysql database as custom source but the default textfilter of autocomplete is "start with" not "contains". I want to change the textfilter to "contains", so that when I search any part of the string, the whole name which contains the searched word will appear in the autocomplete suggestions.
Can anyone help me fix my code?
This is the code i've done so far:
txtSearch.AutoCompleteMode = AutoCompleteMode.SuggestAppend
txtSearch.AutoCompleteSource = AutoCompleteSource.CustomSource
Dim DataCollection As New AutoCompleteStringCollection()
Dim query As String
sqlcon = New MySqlConnection
sqlcon.ConnectionString =
"server=localhost;userid=root;password=root;database=svfmemberlistdb"
Try
sqlcon.Open()
query = " SELECT Name FROM svfmemberlistdb.svfmemberlist "
sqlcmd = New MySqlCommand(query, sqlcon)
sqladr.SelectCommand = sqlcmd
sqladr.Fill(ds)
sqladr.Dispose()
sqlcon.Close()
For Each row As DataRow In ds.Tables(0).Rows
If row.ToString.Contains(txtSearch.Text) Then
DataCollection.Add(row(0).ToString())
End If
Next
Catch ex As Exception
End Try
txtSearch.AutoCompleteCustomSource = DataCollection

I quote here Mitja Bonca's answer on MSDN.
In this case, autocompletemode will just not do. Its code is not meant
for something like it.
You will have to do your own code, to do the filtering on each letter
press.
So I would suggest not to use autocompletemode, and get all the data
(names) into dataTable. When user presses some button ("1" for
example), you start with your filtering, by creating new Datatable
(leave the main one untached - so you can return back to all data when
clearing comboBox by backspace), with Copy() method - to create a full
copy of original one, and use Select method to do the filteing.
This should look something like by using % simbol on both sides of a
string - to filter inbetween - this is what you want!
DataTable AllNames = new DataTable();
//fill it up and leave it untouched!
//to filter comboBox with names that contains pressed characters do in
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
string name = string.Format("{0}{1}", comboBox1.Text, e.KeyChar.ToString()); //join previous text and new pressed char
DataRow[] rows = table.Select(string.Format("FieldName LIKE '%{0}%'", name));
DataTable filteredTable = AllNames.Clone();
foreach(DataRow r in rows)
filteredTable.ImportRow(r);
comboBox1.DataSource = null;
comboBox1.DataSource = filteredTable.DefaultView;
comboBox1.DisplayMember = "FieldName";
}
Reference
EDIT: This is of course a c# answer not VB.NET but it might be helpful to get the concept.

Related

Access VBA Set Focus in Column

good afternoon,
I have an access with a subform (sub_frm_robo2) that has a specific column (CD_SENHA).
In the Form Load event I put the code: (Me.sub_frm_robo2.Form! SENHA.InputMask = "Password")
and I am trying to create a condition that at the moment this Column
(CD_SENHA) receives focus (Me.sub_frm_robo2.Form!SENHA.SetFocus),
the data mask be removed (Me.sub_frm_robo2.Form!SENHA.InputMask = "")
and when the focus changes to the next column return the data mask to the initial format (Me.sub_frm_robo2.Form! PASSWORD = "Password")
Below some images to better exemplify
Before Focus
With Focus
After Focus
I think the code would look something like this
Do While Me.sub_frm_robo2.SetFocus = True
If Me.sub_frm_robo2.Form!SENHA.SetFocus Then
Me.sub_frm_robo2.Form!SENHA.InputMask = ""
End If
Next
Can you help me?
Well, I did not have any help here but I managed to resolve after a few attempts and errors, just to code a code in the event of each column of the subformaluario to make it work. Good luck to everyone
Private Sub CNPJ_AF_GotFocus()
Me.Form!SENHA.InputMask = "Password"
End Sub
Private Sub SENHA_GotFocus()
Me.Form!SENHA.InputMask = ""
End Sub

LibreOffice Basic Macro command converting Calc cellRange to RTF/HTML

My goal is to fill a LibreOffice calc sheet, and silently send a cell range by email when the user clicks the send-off button (and once more to confirm).
So there is three part to this.
A push button with a request to confirm. (Easy and done.)
Select Cell Range and turn it into rich text format (Haven't yet found)
Send rich text email from within the sheet. (Will tackle the "silent" part later)
I tried copying the range to the clipboard with unoService but it seemed over-complicated and full of errors.
Here's what I have:
''''Send by e-mail enriched text
Sub Main
Dim Doc, Sheet, Range, Rtf, Exec as Object
End Sub
'Confirm it
Sub SendTableApproval
If MsgBox ("Ready to email?", MB_YESNO + MB_DEFBUTTON2) = IDYES Then
CopyTable()
End If
End Sub
'Copy it
Sub CopyTable
Doc = ThisComponent
View = Doc.CurrentController
Frame = View.Frame
Sheet = Doc.Sheets.getByIndex(0)
Range = Sheet.getCellrangeByName("a1:f45")
Exec = createUnoService("com.sun.star.frame.DispatchHelper")
View.Select(Range)
Cells = View.getTransferable()
Exec.executeDispatch(Frame, ".uno:Deselect", "", 0, array())
'SimpleMailTo(Cells)
End Sub
'Mail it
Sub SimpleMailTo(body)
Dim launcher as object
Dim eAddress, eSubject, eBody, aHTMLanchor as string
launcher = CreateUnoService("com.sun.star.system.SystemShellExecute")
eAddress = "tu#domo.eg"
eSubject = "Cotidie agenda futuendane"
eBody = body
aHTMLanchor = "mailto:" & eAddress & "?subject=" & eSubject & "&&body=" & eBody
launcher.execute(aHTMLanchor, "", 0)
End Sub
I still do not know after three days of research over methods, properties, uno.
My question is, simply put, How can I convert a transferable content to HTML/RTF?
Simply copying and pasting into an email produces the result you are asking for. The code on the LibreOffice side should look like this.
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
It sounds like you already tried this, but something didn't work. Perhaps you could elaborate on what went wrong.
Another approach would be to write the spreadsheet to a temporary HTML or XHTML file. Then parse the temporary file to grab the part needed for the email.
AFAIK there is no such command to turn a cell range into rich text format with UNO. To do it that way, you would need to loop through each text range of each cell, read its formatting properties and then generate the HTML yourself.
EDIT:
Good idea about XTransferable. The following Java code adapted from the DevGuide gets an HTML string and then prints it. I believe this would be a good solution for your needs.
public void displayHTMLFromClipboard()
{
try
{
Object oClipboard = xMCF.createInstanceWithContext(
"com.sun.star.datatransfer.clipboard.SystemClipboard", xContext);
XClipboard xClipboard = (XClipboard)
UnoRuntime.queryInterface(XClipboard.class, oClipboard);
XTransferable xTransferable = xClipboard.getContents();
DataFlavor[] aDflvArr = xTransferable.getTransferDataFlavors();
System.out.println("Available clipboard formats:");
DataFlavor aChosenFlv = null;
for (int i=0;i<aDflvArr.length;i++)
{
System.out.println(
"MimeType: " + aDflvArr[i].MimeType +
" HumanPresentableName: " + aDflvArr[i].HumanPresentableName );
if (aDflvArr[i].MimeType.equals("text/html"))
{
aChosenFlv = aDflvArr[i];
}
}
System.out.println("");
try
{
if (aChosenFlv != null)
{
System.out.println("HTML text on the clipboard...");
Object aData = xTransferable.getTransferData(aChosenFlv);
String s = new String((byte[])aData, Charset.forName("ISO-8859-1"));
System.out.println(s);
}
}
catch (UnsupportedFlavorException exc)
{
exc.printStackTrace();
}
}
catch(com.sun.star.uno.Exception exc)
{
exc.printStackTrace();
}
}
If you plan to use Basic, it might be a good idea to do some research into the proper way to convert bytes. The code I have below seems to work but is probably unreliable and unsafe, and will not work for many languages. A few of my initial attempts crashed before this finally worked.
Sub DisplayClipboardData
oClipboard = createUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard")
xTransferable = oClipboard.getContents()
aDflvArr = xTransferable.getTransferDataFlavors()
For i = LBound(aDflvArr) To UBound(aDflvArr)
If aDflvArr(i).MimeType = "text/html" Then
Dim aData() As Byte
aData = xTransferable.getTransferData(aDflvArr(i))
Dim s As String
For j = LBound(aData) to UBound(aData)
s = s & Chr(aData(j)) 'XXX: Probably a bad way to do this!
Next j
Print(s)
End If
Next
End Sub
One more suggestion: Python might be a better language choice here. In many ways, using Python with LibreOffice is easier than Java. And unlike Basic, Python is powerful enough to comfortably handle byte strings.

Control name from other window

I need to read a text value from other window and query that value to another application (my question will be around the 1st task)…so,
I’m “spying” other window (some 3rd party application we use in connection with our product) and waiting for “accept” button to be clicked to read a value from a text box. This other application, the dialog box, has multiple text boxes and command buttons.
I made a mouse hook and I’m activating it upon this application appearance. I‘m reading all mouse moves inside this window rectangle; texts, captions, child windows IDs, rectangles, grab left/right/middle/wheel clicks. I can grab the “accept” button click; I CAN SEE the button caption and I can read that window, get the text and determine what button is clicked, etc. Now…
I can read ALL EDIT class values, get their window handles, rectangles, etc., BUT I CANNOT IDENTIFY THEM AS UNIQUE items within the class collection: I need specifically read my desired text box value. Fortunately the text box I’m interested in is ALWAYS COMES FIRST IN MY LOOP when I’m reading texts from EDIT class loop. However I would like to be more specific; making sure that I’m reading the text box with the NAME. I know. During the development I could read that NAME and hard code it in the program. My a suspicion is that control name is not saved in the binary code. My understanding is that control ID, windows handle are created upon windows creation and have absolutely no reference to control name (say: txtOrderNumber). If for buttons I can be specific because of button captions (so, I can determine what button is clicked) I’m locked with EDIT class items and thrown to lucky 1st guess when reading the value.
My question is:
How I can get a control name from another window, for this task I’m interested to know about EDIT class instance names.
Here are some codes (shortened) from the project:
Dim hWnd As IntPtr = FindWindow(Nothing, _windowText)
'API: FindWindowEx
'API: SendMessage
'API: GetClassName
'API: GetWindowTextLength
'API: GetWindowText
'API: WM_GETTEXT
Public Shared Function GetClassValues(_controlClass As String, _hWindow As IntPtr) As List(Of String)
Dim cl As New List(Of String)
'First control handle in that class
Dim hc As IntPtr = FindWindowEx(_hWindow, IntPtr.Zero, _controlClass, vbNullString)
Do
Dim sv As String = GetWindowValue(hc)
cl.Add(sv)
'Next control (after hc) handle
hc = FindWindowEx(_hWindow, hc, _controlClass, vbNullString)
Loop Until hc = 0
Return cl
End Function
Public Shared Function GetWindowValue(_hWindow As IntPtr) As String
If _hWindow = IntPtr.Zero Then Return String.Empty
Dim sz As Integer = 256
Dim bf As IntPtr = Marshal.AllocHGlobal(sz)
Dim pt As IntPtr = SendMessage(_hWindow, WM_GETTEXT, sz, bf)
Dim rs As String = Marshal.PtrToStringUni(bf)
Marshal.Release(bf)
Return rs.Trim
End Function
Public Shared Function GetWindowClassName(_hWindow As IntPtr) As String
Dim ln As Integer = 256
Dim sb As New System.Text.StringBuilder("", ln)
GetClassName(_hWindow, sb, ln)
Return sb.ToString()
End Function
Public Shared Function GetWindowText(_hWindow As IntPtr) As String
Dim ln As Integer
If _hWindow.ToInt32 <= 0 Then Return String.Empty
ln = GetWindowTextLength(_hWindow)
If ln = 0 Then Return String.Empty
Dim sb As New System.Text.StringBuilder("", ln + 1)
GetWindowText(_hWindow, sb, sb.Capacity)
Return sb.ToString()
End Function
I've looked at GetWindowLong and GetDlgCtrlID API and have tried most of the flags with no success so far...
Any tip, clue, direction is appreciated.
Thank you
I made a global mouse hook, this is not a problem and, GetWindowText and WM_GETTEXT works fine. As a matter of fact the program works fine and functional at this point.
Upon detecting a target window I save child window handles in a list collection using EnumChildWindows API and filtering EDIT class windows only (used in connection with modified version of GetClassValues function posted above. The argument for this function is the first EDIT class window handle). Anyway, the way how I arbitrary access my desired text box is to use the saved list for this class windows and access by list index. As I mentioned earlier, fortunately, windows CREATES THIS CHILD windows in consistent order. So, in my case this EDIT class window, the text box “object”, is always the 1st in the list though there are many in the main window.
I would like to get that the text box “object” name, say “txtAccountNumber” as I mentioned earlier…

How can I create a new DataGridView control for each new row in another datagridview in vb.net?

I have a DataGridView control (DataGridView6) that displays a list of managers. I want to generate a new DataGridView everytime I add a new manager to the list and put it in a specific place on my form.
EDIT:
say if i have a main datagridview, and i want to add another datagridview of the same size directly below it, how would i achieve this using the event handler method described in your answer below? im not sure if this is the most efficient way of displaying new members in the program though...
How do can I do this as simply as possible?
Use the DataGridView's "RowsAdded" event. Every time you add a new row (ie manager) to DataGridView6, have the event handler create a new DataGridView and place it where you want it.
It's hard to give a more detailed answer without the specifics of your implementation, but something like that should work.
EDIT - So something like this?
DataGridView dgv = new DataGridView();
dgv.Location = new Point(DataGridView6.Location.X,DataGridView6.Location.Y + <somevalue>);
If you need to keep adding them below this, you could just make a variable NextY that you increment each time you add a new one. You can store them all in a LinkedList or something similar so you can access them easily in order.
I'm not very good at VB, so I've written it in C# first:
DataGridView DataGridView6;
DataGridView DataGridView7;
DataGridViewRow CreateRow(object data) {
DataGridViewRow row = null;
int index = DataGridView6.Rows.Add();
row = DataGridView6.Rows[index];
// row.Cells[0] = something;
// basically, add your date
return row;
}
void DisplayManagerRow(DataGridViewRow row) {
DataGridView7.DataSource = null;
int columns = (DataGridView6.Columns != null) ? DataGridView6.Columns.Count : 0;
if ((row != null) && (0 < columns)) {
DataGridView7.Columns.Clear();
List<DataGridViewColumn> cols = new List<DataGridViewColumn>(columns);
for (int i = 0; i < columns; i++) {
DataGridViewColumn dgvCol = (DataGridViewColumn)DataGridView6.Columns[i].Clone();
DataGridView7.Columns.Add(dgvCol);
}
DataGridView7.Rows.Add(row);
}
}
Now, to try this in VB:
private DataGridView6 As DataGridView
private DataGridView7 As DataGridView
Private Function CreateRow(ByVal data As Object) As DataGridViewRow
Dim index As Int16 = DataGridView6.Rows.Add()
Dim row As DataGridViewRow = DataGridView6.Rows(index)
' row.Cells(0) = something
' basically, add your date
Return row
End Function
Private Sub DisplayManagerRow(ByVal row As DataGridViewRow)
DataGridView7.DataSource = Nothing
Dim columns As Int32 = 0
If Not (DataGridView6.Columns = Nothing) Then
columns = DataGridView6.Columns.Count
End If
If ((row Is Not Nothing) And (0 < columns)) Then
DataGridView7.Columns.Clear()
Dim cols As List<DataGridViewColumn> = new List<DataGridViewColumn>(columns)
For (Dim i As Int32 = 0; i < columns; i++)
Dim dgvCol As DataGridViewColumn = CType(DataGridView6.Columns(i).Clone(), DataGridViewColumn)
DataGridView7.Columns.Add(dgvCol)
Next For
DataGridView7.Rows.Add(row)
End If
End Sub
I can't even remember how to write a For loop in VB! Pathetic!
Does that get the point across, though?
Is this what you are trying to do?

Problem updating values in combobox in vb.net

I have this code, but I have a problem.
When I update but do not really made any changes to the value and press the update button, the data becomes null. And it will seem that I deleted the value.
I've taught of a solution, that is to add both combobox1.selectedtext and combobox1.selecteditem to the function. But it doesn't work.
combobox1.selecteditem is working when you try to alter the values when you update. But will save a null value when you don't alter the values using the combobox
combobox1.selectedtext will save the data into the database even without altering.
But will not save the data if you try to alter it.
-And I incorporated both of them, but still only one is performing, and I think it is the one that I added first:
Dim shikai As New Updater
Try
shikai.id = TextBox1.Text
shikai.fname = TextBox2.Text
shikai.mi = TextBox3.Text
shikai.lname = TextBox4.Text
shikai.ad = TextBox5.Text
shikai.contact = TextBox9.Text
shikai.year = ComboBox1.SelectedText
shikai.section = ComboBox2.SelectedText
shikai.gender = ComboBox3.SelectedText
shikai.religion = ComboBox4.SelectedText
shikai.year = ComboBox1.SelectedItem
shikai.section = ComboBox2.SelectedItem
shikai.gender = ComboBox3.SelectedItem
shikai.religion = ComboBox4.SelectedItem
shikai.bday = TextBox6.Text
shikai.updates()
MsgBox("Successfully updated!")
Please help, what would be a simple workaround to solve this problem?
a few things to remember ---
a 'selected____' anything is only non-null when something is, uhm, SELECTED. To ensure that SOMETHING is selected even at start add a line like: ComboBox1.SelectedIndex = 0.
If your recordset has non-string types (like a DATE field might be) then be sure to first check then coerce the string coming back as TEXT to the correct type. I.e....
if isDate(ComboBox1.SelectedText) then ... 'its ok to use this coerced text.
Since a combobox (as well as a listbox) can hold an entire CLASS (i.e. any kind of OBJECT) ... any SelectedItem assignment had better match EXACTLY to the type that was .Items.Add 'ed originally to the control.