In this example:
TestSub.vbs
a = "String"
TestSub a
Sub TestSub(a)
MsgBox "Test " & a
End Sub
The Sub function works just fine and displays the text "Test String" in the MsgBox
But in this example (embedded in a HTA)
TestSub2.VBS
Sub getdata
NameID = "name123"
' NameID = 123 ' (This works)
strHTML0 = strHTML0 & _
"<select>" & _
"<option onclick='UpdateSelect("& NameID &")' language='vbscript'>" & _
NameID & _
"</option>" & _
"</select>"
SelectBox.innerHTML = strHTML0
End sub
Sub UpdateSelect(NameID)
MsgBox "Test " & NameID
End sub
The NameID is displayed in the selectbox, but when you call the sub it doesn't display in the messagebox, however, if you set NameID = 123 it displays the integer in the messagebox
Why can it only display integers and how can you make it display a string?
Posted whole .hta on pastebin
You are concatenating strings and must delimiter NameID value in this way:
"<option onclick='UpdateSelect("""& NameID &""")' language='vbscript'>" & _
Related
I have a table name 'product', and product_name, category as a fields. I want to add the product_name row value to the combobox where the category value is repeated....
product_name | category
--------------+----------
Ceiling fan | fan
Table fan | fan
Wall fan | fan
I try the following code but without do while statement it gives one value and when i am trying to loop it the machine hangs. Plz help
Option explicit
Private sub cboCategories_Click()
cboProducts.clear
rs.open "select * from product". cn, adOpenDynamic. adLockOptimistic
With rs
.find "category=' " & cbiCategories.Text & " ' "
.moveFirst
With rs(0).value
Do until rs.EOF
cboProducts.AddItem rs(0).Value
rs.MoveNext
Loop
End with
End with
End sub
This is my table at present. I want to get the product_name field value to the combobox where the category name is the same, such as 'fan'
There are several ways to skin such a cat. One is to source your ComboBox data from a disconnected hierarchical Recordset created using the Data Shaping Service.
This example assumes a CSV file with a header row, but the same thing works with a Jet or other database table:
Option Explicit
Private rsShapedProducts As ADODB.Recordset
Private Sub cboCategories_Click()
With cboProducts
.Clear
With rsShapedProducts
.MoveFirst
.Find "[Category]='" & cboCategories.List(cboCategories.ListIndex) & "'"
With ![Products].Value
.MoveFirst
Do Until .EOF
cboProducts.AddItem ![Product].Value
.MoveNext
Loop
End With
End With
.ListIndex = 0
End With
End Sub
Private Sub cboProducts_Click()
lblSelection.Caption = cboCategories.List(cboCategories.ListIndex) _
& " -> " _
& cboProducts.List(cboProducts.ListIndex)
End Sub
Private Sub Form_Load()
Set rsShapedProducts = New ADODB.Recordset
With rsShapedProducts
.CursorLocation = adUseClient
.Open "SHAPE {" _
& "SELECT [Category], [Product] FROM [products.txt] " _
& "ORDER BY [Category], [Product]" _
& "} AS [Products] COMPUTE [Products] BY [Category]", _
"Provider=MSDataShape;Data Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source='" & App.Path & "';Extended Properties='Text;Hdr=Yes'", _
adOpenStatic, _
adLockReadOnly, _
adCmdText
Set .ActiveConnection = Nothing
Do Until .EOF
cboCategories.AddItem ![Category].Value
.MoveNext
Loop
End With
Show
cboCategories.ListIndex = 0
End Sub
Private Sub Form_Unload(Cancel As Integer)
rsShapedProducts.Close
End Sub
Test data I used:
Category,Product
Fan,Ceiling Fan
Fan,Table Fan
Fan,Wall Fan
Lamp,Floor Lamp
Lamp,Table lamp
Lamp,Desk Lamp
Table,Coffee Table
Table,End Table
Table,Kitchen Table
Table,Dining Table
Table,Card Table
Private Function IsInCollection(ByVal Coll As Collection, CollKey As String) As Boolean
On Error GoTo errHandler
Dim b As Variant
b = Coll(CollKey)
IsInCollection = True
errHandler:
Err.Clear
Exit Function
End Function
Public Sub FillCombo()
Dim rs As Adodb.Recordset
Dim Coll As New Collection
Dim strNewValue As String
Set rs = fillMyRs
Do While Not rs.EOF
strNewValue = rs.Fields("category").Value
If IsInCollection(Coll, strNewValue) Then
strNewValue = strNewValue & " - " & rs.Fields("product_name").Value
Else
Coll.Add strNewValue, strNewValue
End If
Combo1.AddItem strNewValue
rs.MoveNext
Loop
End Sub
I'm using vb6 and sql server.in which on the form load I'm filling 4 combobox.But its taking 10 to 12 minutes to load the form.
My code is as follows:
Can anybody help me to make the form load fast?
Public Sub fillCombo(Id As String, Name As String, Table As String, obj As Object, Optional cond As String)
Dim rsF As New ADODB.Recordset
With rsF
If .State = adStateOpen Then .Close
If cond = "" Then
.Open "Select " & Id & "," & Name & " From " & Table & " Order by " & Name, Cn, adOpenKeyset, adLockOptimistic
Else
.Open "Select " & Id & "," & Name & " From " & Table & " Where " & cond & " Order by " & Name, Cn, adOpenKeyset, adLockOptimistic
End If
obj.Clear
'obj.AddItem ""
While Not .EOF
obj.AddItem .Fields(1)
obj.ItemData(obj.NewIndex) = .Fields(0)
.MoveNext
Wend
.Close
End With
End Sub
function call is as follows:
fillCombo "JobId", "JobName", "Jobs", cboJob
The problem (I believe) is that you are using a server-side recordset. When you do this, you are making one round trip to the server for each iteration of your loop, which is, as you have found, glacially slow.
The solution is to create a client-side recordset. That sends the data from the server to the client in one go. Keep in mind that client-side recordsets are always static; if you set the CursorType to adOpenKeyset the CursorLocation to adUseClient, the latter will override the former and your CursorType will still be adOpenStatic.
Here's a mod to your code, with various improvements (in particular, with your atrocious indenting corrected; you might consider being a bit nicer to the poor folks who have to work with your code down the line when you write it):
Public Sub fillCombo(Id As String, Name As String, Table As String, obj As Object, Optional cond As String)
Dim sql As String
Dim rsF As ADODB.Recordset 'Don't use "As New" in VB6, it's slow
'sql variable with ternary conditional (IIf) is cleaner way to do what you want
sql = "Select " & Id & "," & Name & " From " & Table & IIf(cond = "", "", " Where " & cond) & " Order by " & Name
Set rsF = New ADODB.Recordset
With rsF
.CursorLocation = adUseClient 'Client-side, static cursor
'If .State = adStateOpen Then .Close --Get rid of this: if you just created rsF, it can't be open, so this is a waste of processor cycles
.Open sql, Cn 'Much prettier, yes? :)
obj.Clear 'All this is fine
Do Until .EOF
obj.AddItem .Fields(1)
obj.ItemData(obj.NewIndex) = .Fields(0)
.MoveNext
Loop
.Close
End With
End Sub
hi,
i write programme in vb6 and depend on ms access database
i create table in ms access (users)
then i make module :-
Public DB As New ADODB.Connection
Public RS As New ADODB.Recordset
Public RSS As New ADODB.Recordset
Public SQLS As String
Public UserNames As String
Public UserPassword As String
Sub POOLCONNECTION()
If DB.State = adStateOpen Then DB.Close
DB.Provider = "Microsoft.JET.OLEDB.4.0"
DB.Open App.Path & "\data.mdb"
End Sub
and i make some forms for user :-
1- i make check user form to create administrator user for the first time to use. if there are no records this form will create admin user
code:-
Private Sub Form_Load()
Text1 = " "
Text2 = " "
Text3 = " "
POOLCONNECTION
SQLS = " Select * From Users "
If RS.State = adStateOpen Then RS.Close
RS.Open SQLS, DB, adOpenKeyset, adLockPessimistic
If Not RS.RecordCount = 0 Then
FRMLOGIN.Show
Unload Me
End If
End Sub
Private Sub save_Click()
If Text1 = " " Then
MsgBox " Sorry, You Must Type Username ", vbCritical + vbMsgBoxRight, "Error"
Text1.SetFocus
Exit Sub
End If
If Text2 = " " Then
MsgBox " Please Type Old Password ", vbCritical + vbMsgBoxRight, " Error "
Text2.SetFocus
Exit Sub
End If
SaveMsg = MsgBox(" åá ÊÑíÏ ÇäÔÇÁ ãÏíÑ ááäÙÇã ?", vbQuestion + vbMsgBoxRight + vbYesNo, " Êã ÇáÍÝÙ ")
If SaveMsg = vbYes Then
RS.AddNew
RS![UserName] = Text1
RS![Password] = Text2
RS![GAdd] = True
RS![GEdit] = True
RS![GPrint] = True
RS![GCreateUser] = True
RS![GDelete] = True
RS.Update
MsgBox " Êã ÍÝÙ ÇáÈíÇäÇÊ", vbInformation + vbMsgBoxRight, " Saved "
' Save This Informations
UserNames = Text1
UserPassword = Text2
' Long Main
Set RS = Nothing
Set DB = Nothing
MDIForm1.Show
Unload Me
End If
End Sub
for the second time use after i have making adimn user login form show and i try to login with the admin user .. eof didn't read the records
login code :
Private Sub Command1_Click()
If Text1 = "" Or Text2 = "" Then
MsgBox " ÚÝæÇ íÌÈ ßÊÇÈÉ ÇÓã ÇáãÓÊÎÏã æßáãÉ ÇáãÑæÑ ", vbCritical + vbMsgBoxRight, " ÎØà Ýì ÇáÏÎæá"
Exit Sub
End If
SQLS = "Select * From Users Where Username = ' " & Text1 & " ' And Password = ' " & Text2 & " ' "
If RS.State = adStateOpen Then RS.Close
RS.Open SQLS, DB, adOpenKeyset, adLockPessimistic
If RS.EOF Then
MsgBox " Sorry, The Username And Password Is Wrong ! ", vbCritical + vbMsgBoxRight, " Error Login "
Else
Set RS = Nothing
Set DB = Nothing
MDIForm1.Show
Unload Me
End If
End Sub
Private Sub Command2_Click()
Unload Me
End Sub
Private Sub Form_Load()
POOLCONNECTION
End Sub
Private Sub text1_keypress(keyAscii As Integer)
If keyAscii = 13 Then
Text2.SetFocus
End If
End Sub
Private Sub text2_keypress(keyAscii As Integer)
If keyAscii = 13 Then
Command1.SetFocus
End If
End Sub
Remove unnecessary spaces before and after texts:
SQLS = "Select * From Users Where Username = '" & Text1 & "' And Password = '" & Text2 & "' "
I'm trying to see if I can programatically trap an AutoFilter sort event, get the sort criteria and then apply that same sort criteria to an AutoFilter in a second worksheet.
So far it seems as though I have to trigger the Worksheet_Calculate() event. And this I've done. Then I have to check if the AutoFilter sort criteria was changed. If it wasn't, exit sub. If it was, collect the criteria and run it through a separate sub, which does the exact same sorting on an AutoFilter in a separate worksheet.
The general idea is that whenever one of these two AutoFilters are sorted, the AutoFilter in the other sheet should be sorted the exact same way.
I've tried to do something like this (I had to add an Excel formula to actually make the calculate event trigger):
Private Sub Worksheet_Calculate()
Dim wbBook as Workbook
Dim wsSheet as Worksheet
Dim rnData as Range
Set wbBook = ThisWorkbook
Set wsSheet = wbBook.Worksheets("Sheet1")
With wsSheet
Set dnData = .UsedRange
End With
End Sub
But I can't seem to manage to collect the criteria, I've tried several things and adding a watch to the dnData doesn't even reveal any AutoFilter property. Can someone shed any light on this?
Here is a way to get the autofilter criteria:
Sub test()
Dim Header As Range
Dim sMainCrit As String, sANDCrit As String, sORCrit As String
Set Header = Range("A2:C2")
With Header.Parent.AutoFilter
With .Filters(Header.Column - .Range.Column + 1)
If Not .On Then
MsgBox ("no criteria")
Exit Sub
End If
sMainCrit = .Criteria1
If .Operator = xlAnd Then
sANDCrit = .Criteria2
ElseIf .Operator = xlOr Then
sORCrit = .Criteria2
End If
End With
End With
MsgBox ("Main criteria: " & sMainCrit & Chr(13) & "AND Criteria:" & sANDCrit & Chr(13) & "OR Criteria" & sORCrit)
End Sub
Adapted from ozgrid
Here are some notes on what I see as your requirements.
Dim rv As AutoFilter ''Object
Set rv = Sheet1.AutoFilter
''Just for curiosity
Debug.Print rv.Sort.Header
Debug.Print rv.Sort.SortFields.Count
Debug.Print rv.Sort.SortFields.Item(1).SortOn
Debug.Print rv.Sort.Rng.Address
Debug.Print rv.Sort.SortFields.Item(1).Key.Address
''One key only, but it is easy enough to loop and add others
Sheet2.Range(rv.Sort.Rng.Address).Sort _
key1:=Sheet2.Columns(rv.Sort.SortFields(1).Key.Column), _
Header:=xlYes
Found this code:
Sub ShowAutoFilterCriteria()
' John Green et. al: Excel 2000 VBA Programmer?s Reference, S. 379f
' 09.01.2005
Dim oAF As AutoFilter
Dim oFlt As Filter
Dim sField As String
Dim sCrit1 As String
Dim sCrit2 As String
Dim sMsg As String
Dim i As Integer
' Check if the sheet is filtered at all
If ActiveSheet.AutoFilterMode = False Then
MsgBox "The sheet does not have an Autofilter"
Exit Sub
End If
' Get the sheet?s Autofilter object
Set oAF = ActiveSheet.AutoFilter
' Loop through the Filters of the Autofilter
For i = 1 To oAF.Filters.Count
' Get the field name form the first row
' of the Autofilter range
sField = oAF.Range.Cells(1, i).Value
' Get the Filter object
Set oFlt = oAF.Filters(i)
' If it is on...
If oFlt.On Then
' Get the standard filter criteria
sMsg = sMsg & vbCrLf & sField & oFlt.Criteria1
' If it?s a special filter, show it
Select Case oFlt.Operator
Case xlAnd
sMsg = sMsg & " And " & sField & oFlt.Criteria2
Case xlOr
sMsg = sMsg & " Or " & sField & oFlt.Criteria2
Case xlBottom10Items
sMsg = sMsg & " (bottom 10 items)"
Case xlBottom10Percent
sMsg = sMsg & " (bottom 10%)"
Case xlTop10Items
sMsg = sMsg & " (top 10 items)"
Case xlTop10Percent
sMsg = sMsg & " (top 10%)"
End Select
End If
Next i
If msg = "" Then
' No filters are applied, so say so
sMsg = "The range " & oAF.Range.Address & " is not filtered."
Else
' Filters are applied, so show them
sMsg = "The range " & oAF.Range.Address & " is filtered by:" & sMsg
End If
' Display the message
MsgBox sMsg
End Sub
Works fine on my tests! I've changed a small part of it to support complex criteria:
' Get the standard filter criteria
If IsArray(oFlt.Criteria1) Then
Dim x As Integer
sMsg = sMsg & vbCrLf & sField
For x = 1 To UBound(oFlt.Criteria1)
sMsg = sMsg & "'" & oFlt.Criteria1(x) & "'"
Next x
Else
sMsg = sMsg & vbCrLf & sField & "'" & oFlt.Criteria1 & "'"
End If
Original link: http://www.vbaexpress.com/forum/archive/index.php/t-7564.html
I want to write a VBS macro to auto generate an email in outlook and attach a word document. I currently have a macro that does this for excel, but I can't get it to work for Word. I can't figure out for the life of me what my "FName= " should be. Any suggestions or help would be greatly appreciated. Here is what I have:
Sub AutoEmail()
On Error GoTo Cancel
Dim Resp As Integer
Resp = MsgBox(prompt:=vbCr & "Yes = Review Email" & vbCr & "No = Immediately Send" & vbCr & "Cancel = Cancel" & vbCr, _
Title:="Review email before sending?", _
Buttons:=3 + 32)
Select Case Resp
'Yes was clicked, user wants to review email first
Case Is = 6
Dim myOutlook As Object
Dim myMailItem As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = ActiveWord & "\" & ActiveWord.Name
With otlNewMail
.To = ""
.CC = ""
.Subject = ""
.Body = "Good Morning," & vbCr & vbCr & "" & Format(Date, "MM/DD") & "."
.Attachments.Add FName
.Display
End With
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If no is clicked
Case Is = 7
Dim myOutlok As Object
Dim myMailItm As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = ActiveWorkbook.Path & "\" & ActiveWorkbook.Name
With otlNewMail
.To = ""
.CC = ""
.Subject = ""
.Body = "Good Morning," & vbCr & vbCr & " " & Format(Date, "MM/DD") & "."
.Attachments.Add FName
.Send
'.Display
'Application.Wait (Now + TimeValue("0:00:01"))
'Application.SendKeys "%s"
End With
'otlApp.Quit
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If Cancel is clicked
Case Is = 2
Cancel:
MsgBox prompt:="No Email has been sent.", _
Title:="EMAIL CANCELLED", _
Buttons:=64
End Select
End Sub
May it is a bit late, but I want to solve it for future use.
You want to have the active document as your file name (FName).
FName = Application.ActiveDocument.Path + "\" + Application.ActiveDocument.Name
' .Path returns only the Path where the file is saved without the file name like "C:\Test"
' .Name returns only the Name of the file, including the current type like "example.doc"
' Backslash is needed because of the missing backslash from .Path
otlNewMail.Attachements.Add FName
May you also want to save your current document before sending it via outlook, otherwise you will send the document without the changes made.
Function SaveDoc()
ActiveDocument.Save
End Function
I hope that this will help others, because the code from the question helped me a lot while scripting a similar script.