How can I reference a dynamically created ID in HTA (vbscript)? - vbscript

See slimmed down code. I'm essentially creating a list of items (printers) along with a dynamically created unique radio button ID, and then I'd like to be able reference said Radio ID in order to toggle the Checked between True/False in Sub SetDefaultPrinter. Why? Because using Add Devices / Search is too hard for some of our users, hence, a cute little GUI. Why dynamic? Because I have multiple separate networks and I'd prefer the script to adjust itself as needed.
<html>
<head>
<title>My HTML application</title>
<HTA:APPLICATION
APPLICATIONNAME="My HTML application"
ID="MyHTMLapplication"
VERSION="1.0"/>
</head>
<script language="VBScript">
Public jj, strPrinters, strModels, strLocations
Sub Window_OnLoad
strPrinters = Array("Printer1", "Printer2")
strModels = Array("HP Color LaserJet 4525", "HP Color LaserJet 4525")
strLocations = Array("Room 1", "Room 2")
jj = UBound(strPrinters)
Call OnClickGo()
End Sub
Sub OnClickGo()
DataArea1.InnerHTML = ""
For i = 0 To jj
DataArea1.InnerHTML = DataArea1.InnerHTML & "<BR><font style=color:green;font-weight=bold;>" &_
"<input type=""" & "radio""" & " name=""" &_
strPrinters(i) & "Radio""" & " id=""" & "Radio" & i & """" &_
" title=""" & "Clicking here will set " & strPrinters(i) & " as default printer.""" &_
" onclick=""" & "SetDefaultPrinter(" & i & ")""" & " onmouseover=""" & "Pointer""" &_
" onmouseout=""" & "DefaultCursor""" & "></input>" &_
"<span id=""" & strPrinters(i) & "Span""" &_
" title=""" & "Click here delete printer mapping for " & strPrinters(i) & """" &_
" onmouseover=""" & "Pointer""" & " onmouseout=""" & "DefaultCursor""" &_
" onclick=""" & "OnClickDelete(" & i & ")""" &_
">" & strPrinters(i) & ", " & strModels(i) & ", Location: " & strLocations(i) & "</span></font>"
Next
End Sub
'========================================
'= Set Default Printer ==================
'========================================
Sub SetDefaultPrinter(ii)
DataArea2.InnerHTML = strPrinters(ii) & " would have been set as default if this was fully functional."
'
' Radio0 and Radio1 are dynamically created IDs, *really* want to somehow
' dynamically reference the dynamically created IDs.
' i.e. something like
' If ii <> 0 Then (Radio & ii).checked = False
'
If ii <> 0 Then Radio0.checked = False
If ii <> 1 Then Radio1.checked = False
End Sub
'========================================
'= Delete Printer Mapping ===============
'========================================
Sub OnClickDelete(ii)
DataArea2.InnerHTML = strPrinters(ii) & " would have been deleted if this was fully functional."
'Set wshnetwork = CreateObject("WScript.Network")
'wshnetwork.RemovePrinterConnection "\\SERVER\" & strPrinters(PrinterToDelete)
End Sub
'========================================
'= MOUSE Pointers =======================
'========================================
Sub Pointer
document.body.style.cursor = "hand"
End Sub
Sub DefaultCursor
document.body.style.cursor = "default"
End Sub
</script>
<body bgcolor="white">
<span id="DataArea1"></span>
<BR><BR><BR>
<span id="DataArea2"></span>
</body>
</html>

user2345916, I have modified your code where the variables pass like you wanted. I left your comments intact, so you can pick up where you left off. Hope this helps!
Basically, the answer to your problem lies within the button's "ID", "VALUE" and "ONCLICK" values.
The ONCLICK='SetDefaultPrinter(" & i & ")' will pass the looped number to the SubRoutine.
The SetDefaultPrinter(Radioii) sets a variable from the "ONCLICK" field of the button that sends you to that SubRoutine (In this case, it's a 0 or 1).
The "FileName = document.getElementById("Radio" & Radioii).value" gets the "VALUE" field of the button that matches the "ID" field that is set between the "()", which in your case is also the variable that was pulled from the ONCLICK.
From here, you can use (FileName) variable to do whatever you want (Match IF/THEN, etc)
<script language=vbscript>
Sub Window_OnLoad
window.resizeTo 500,300
strPrinters = Array("Printer 1", "Printer 2")
strModels = Array("HP Color LaserJet 4525", "HP Color LaserJet 4525")
strLocations = Array("Room 1", "Room 2")
jj = UBound(strPrinters)
For i = 0 To jj
strHTML1 = "<span id='Delete" & i & "' value='" & strPrinters(i) & "'title='Click here delete printer mapping for " & strPrinters(i) & "' onmouseover='Pointer' onmouseout='DefaultCursor' onclick='OnClickDelete(" & i & ")'> " & strPrinters(i) & " - " & strModels(i) & ", Location: " & strLocations(i) & "</span>"
strHTML2 = strHTML2 & "<input type='radio' name='radio' value='" & strPrinters(i) & "' id='Radio" & i & "' title='Clicking here will set " & strPrinters(i) & " as default printer.' onclick='SetDefaultPrinter(" & i & ")' onmouseover='Pointer' onmouseout='DefaultCursor'>" &_
"" & strHTML1 & "</input><br>"
DataArea1.InnerHTML = strHTML2
Next
End Sub
'========================================
'= Set Default Printer ==================
'========================================
Sub SetDefaultPrinter(Radioii)
FileName = document.getElementById("Radio" & Radioii).value
DataArea3.InnerHTML = Filename & " would have been set as default if this was fully functional."
'
' Radio0 and Radio1 are dynamically created IDs, *really* want to somehow
' dynamically reference the dynamically created IDs.
' i.e. something like
' If ii <> 0 Then (Radio & ii).checked = False
'
If Radioii = 0 Then Radio0 = False
If Radioii = 1 Then Radio1 = False
End Sub
'========================================
'= Delete Printer Mapping ===============
'========================================
Sub OnClickDelete(Deleteii)
RemoveName = document.getElementById("Delete" & Deleteii).value
DataArea3.InnerHTML = RemoveName & " would have been deleted if this was fully functional."
'Set wshnetwork = CreateObject("WScript.Network")
'wshnetwork.RemovePrinterConnection "\\SERVER\" & strPrinters(PrinterToDelete)
End Sub
'========================================
'= MOUSE Pointers =======================
'========================================
Sub Pointer
document.body.style.cursor = "hand"
End Sub
Sub DefaultCursor
document.body.style.cursor = "default"
End Sub
</script>

Related

Is there a way to organize WriteLine output into columns in a text file?

Is there any way to separate the WriteLine data output in a text file into columns (ex: Date | Location | Size)?
I've yet to see any information regarding this anywhere online, unsure if possible since the data being written isn't static. Would I need an entirely different function in order to have the script handle the formatting of the text file?
Option Explicit
Dim sDirectoryPath,Search_Days,r_nr,iDaysOld,CmdArg_Object,lastModDate
Dim oFSO,oFolder,oFileCollection,oFile,oTF,Inp, SubFolder,fullpath
Set CmdArg_Object = Wscript.Arguments
Select Case (CmdArg_Object.Count)
Case 3
sDirectoryPath = CmdArg_Object.item(0)
Search_Days = CmdArg_Object.item(1)
r_nr = CmdArg_Object.item(2)
Case Else
WScript.Echo "SearchFiles.vbs requires 3 parameters:" & _
vbCrLf & "1) Folder Path" & _
vbCrLf & "2) # Days to Search" & _
vbCrLf & "3) Recursive option (r/nr)"
WScript.Quit
End Select
Set oFSO = CreateObject("Scripting.FileSystemObject")
iDaysOld=Date+(-1*Search_Days)
Inp = InputBox("Please Enter Desired Location of Log File:")
If Inp= "" Then
Set oTF = oFSO.CreateTextFile("C:\output.txt")
Else
Set oTF = oFSO.CreateTextFile(oFSO.BuildPath(Inp, "output.txt"))
End If
Set oFolder = oFSO.GetFolder(sDirectoryPath)
Set oFileCollection = oFolder.Files
WScript.Echo Now & " - Beginning " & Search_Days & " day search of " & sDirectoryPath
If r_nr = "r" Then
oTF.WriteLine ("Search Parameters-") & _
vbCrLf & "DirectoryPath: " & sDirectoryPath & _
vbCrLf & "Older than: " & Search_Days &" Days " & _
vbCrLf & "Recursive/Non-Recursive: " & r_nr & _
vbCrLf & "------------------ "
TraverseFolders oFSO.GetFolder(sDirectoryPath)
Function TraverseFolders (FolderName)
For Each SubFolder In FolderName.SubFolders
For Each oFile In SubFolder.Files
lastModDate = oFile.DateLastModified
If (lastModDate <= iDaysOld) Then
oTF.WriteLine (oFile.DateLastModified) & " " & oFile.Path
End If
Next
TraverseFolders(Subfolder)
Next
End Function
Else
oTF.WriteLine ("Search Parameters:") & _
vbCrLf & "DirectoryPath: " & sDirectoryPath & _
vbCrLf & "Older than: " & Search_Days &" Days " & _
vbCrLf & "Recursive/Non-Recursive: " & r_nr & _
vbCrLf & "------------------------- "
For Each oFile In oFileCollection
lastModDate = oFile.DateLastModified
If (lastModDate <= iDaysOld) Then
oTF.WriteLine (oFile.DateLastModified) & " " & oFile.Path
End If
Next
End If
If Inp = "" Then
WScript.Echo "Now - Finished! Results Placed in: C:\output.txt"
Else
WScript.Echo "Now - Finished! Results Placed in: " & Inp
End If
You could use a delimiter-separated output format, e.g. like this:
Delim = vbTab
oTF.WriteLine "DateLastModified" & Delim & "Size" & Delim & "Path"
...
For Each oFile in oFileCollection
oTF.WriteLine oFile.DateLastModified & Delim & oFile.Size & Delim & oFile.Path
Next
Using tabs and a carefully chosen order of fields has the advantage that editors will display the content in (mostly) proper columns and you can import it as CSV in other programs.
If you're aiming for a fixed-width format you need to pad the data yourself e.g. with custom padding functions, e.g.
Function LPad(s, l)
n = 0
If l > Len(s) Then n = l - Len(s)
LPad = String(n, " ") & s
End Function
Using a StringBuilder object would also be an option, as described in this answer to another question.

Trigger some vbs code on filename change

I would like to be able run some custom vb script code upon filename change (for instance to keep a list of newly created files or the ones which changed their name).
The vbs should be called on every filename change happening within a specified folder.
I know how to do that with a full directory scan but I would like to find a more efficient method, for instance by the mean of a sort of OS hook calling my code.
Any way to do that ?
Thank you,
A.
There are two simple WMI examples, tracing changes for *.txt files in C:\Test\ folder.
First one is for synchronous event processing:
Option Explicit
Dim oWMIService, oEvents, s
Set oWMIService = GetObject("WinMgmts:\\.\root\CIMv2")
Set oEvents = oWMIService.ExecNotificationQuery( _
"SELECT * FROM __InstanceOperationEvent " & _
"WITHIN 1 WHERE " & _
"TargetInstance ISA 'CIM_DataFile' AND " & _
"TargetInstance.Drive = 'C:' AND " & _
"TargetInstance.Extension = 'txt' AND " & _
"TargetInstance.Path = '\\Test\\'")
Do
With oEvents.NextEvent()
s = "Event: " & .Path_.Class & vbCrLf
With .TargetInstance
s = s & "Name: " & .Name & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Creation Date: " & .CreationDate & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
s = s & "Last Accessed: " & .LastAccessed & vbCrLf
End With
If .Path_.Class = "__InstanceModificationEvent" Then
With .PreviousInstance
s = s & "Previous" & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
End With
End If
End With
WScript.Echo s
Loop
The second is for asynchronous event processing:
Option Explicit
Dim oWMIService, oSink
Set oWMIService = GetObject("WinMgmts:\\.\root\CIMv2")
Set oSink = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")
oWMIService.ExecNotificationQueryAsync oSink, _
"SELECT * FROM __InstanceOperationEvent " & _
"WITHIN 1 WHERE " & _
"TargetInstance ISA 'CIM_DataFile' AND " & _
"TargetInstance.Drive = 'C:' AND " & _
"TargetInstance.Extension = 'txt' AND " & _
"TargetInstance.Path = '\\Test\\'"
Do
WScript.Sleep 1000
Loop
Sub Sink_OnObjectReady(oEvent, oContext)
Dim s
With oEvent
s = "Event: " & .Path_.Class & vbCrLf
With .TargetInstance
s = s & "Name: " & .Name & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Creation Date: " & .CreationDate & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
s = s & "Last Accessed: " & .LastAccessed & vbCrLf
End With
If .Path_.Class = "__InstanceModificationEvent" Then
With .PreviousInstance
s = s & "Previous" & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
End With
End If
End With
WScript.Echo s
End Sub
More info on CIM_DataFile instance properties you can find by the link on MSDN.

WQL-Statement to check an application's event log

I would like to analyze the event log of a special windows application (Windows 7 Enterprise, 64Bit).
I need a special event which is logged some seconds ago.
Here is my VBScript code, which produces a completely wrong result (wrong number of events):
strComputer = "." ' Dieser Computer
' Retrieving Specific Events from an Event Log
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")
Const CONVERT_TO_LOCAL_TIME = True
Set dtmStartDate = CreateObject("WbemScripting.SWbemDateTime")
Set dtmEndDate = CreateObject("WbemScripting.SWbemDateTime")
dtmStartDate.SetVarDate dateadd("s", -10, now()) ' CONVERT_TO_LOCAL_TIME
dtmEndDate.SetVarDate now() ' CONVERT_TO_LOCAL_TIME
dim var_wql
var_wql = "SELECT * FROM Win32_NTLogEvent WHERE Logfile = '< ... >' AND SourceName = '< ... >' AND EventCode = '< ... >' AND (TimeWritten >= '" & dtmStartDate & "') AND (TimeWritten < '" & dtmEndDate & "')"
Set colLoggedEvents = objWMIService.ExecQuery(var_wql)
...
The number of rows (anzahl = colLoggedEvents.count) must be 0 or 1, anything else is impossible.
What is wrong with the wql statement? I would like to check the last seconds in the past (from now).
Thanks.
Tommy
Syntax error. If I change the objWMIService line to this, it works for me.
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & strComputer & "\root\cimv2")
Updated to grab ALL event logs created in the last 10 secs and write to log file.
On Error Resume Next
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
strSystemDrive = WshShell.ExpandEnvironmentStrings("%SystemDrive%")
Const CONVERT_TO_LOCAL_TIME = True
Set dtmStartDate = CreateObject("WbemScripting.SWbemDateTime")
Set dtmEndDate = CreateObject("WbemScripting.SWbemDateTime")
dtmStartDate.SetVarDate dateadd("s", -10, now()) ' CONVERT_TO_LOCAL_TIME
dtmEndDate.SetVarDate now() ' CONVERT_TO_LOCAL_TIME
var_wql = "SELECT * FROM Win32_NTLogEvent WHERE (TimeWritten >= '" & dtmStartDate & "') AND (TimeWritten < '" & dtmEndDate & "')"
Set LogFile = objFSO.CreateTextFile(strSystemDrive & "\Temp\EvtLog.txt", True)
Set colLoggedEvents = objWMIService.ExecQuery(var_wql)
For Each objEvent in colLoggedEvents
LogFile.WriteLine "Computer Name : " & objEvent.ComputerName
LogFile.WriteLine "Logfile : " & objEvent.Logfile
LogFile.WriteLine "Type : " & objEvent.Type
LogFile.WriteLine "User : " & objEvent.User
LogFile.WriteLine "Category : " & objEvent.Category
LogFile.WriteLine "Category String : " & objEvent.CategoryString
If IsArray(objEvent.Data) Then
For i = 0 To UBound(objEvent.Data)
strData = strData & objEvent.Data(i) & ","
Next
LogFile.WriteLine "Data : " & strData
Else
LogFile.WriteLine "Data : " & objEvent.Data
End If
LogFile.WriteLine "Event Code : " & objEvent.EventCode
LogFile.WriteLine "Event Identifier : " & objEvent.EventIdentifier
LogFile.WriteLine "Message : " & objEvent.Message
LogFile.WriteLine "Record Number : " & objEvent.RecordNumber
LogFile.WriteLine "Source Name : " & objEvent.SourceName
LogFile.WriteLine "Time Generated : " & objEvent.TimeGenerated
LogFile.WriteLine "Time Written : " & objEvent.TimeWritten
If IsArray(objEvent.InsertionStrings) Then
For i = 0 To UBound(objEvent.InsertionStrings)
strInsert = strInsert & objEvent.InsertionStrings(i) & ","
Next
LogFile.WriteLine "Insertion Strings: " & strInsert
Else
LogFile.WriteLine "Insertion Strings: " & objEvent.InsertionStrings
End If
LogFile.WriteLine "----------------------------------------------------------------------------------------------------------"
Next
Output sample (Not all fields used for every event) -
----------------------------------------------------------------------------------------------------------
Computer Name : Randy-PC
Logfile : Application
Type : Information
User :
Category : 0
Category String :
Data :
Event Code : 9019
Event Identifier : 1073750843
Message : The Desktop Window Manager was unable to start because the desktop composition setting is disabled
Record Number : 37395
Source Name : Desktop Window Manager
Time Generated : 20160903031728.000000-000
Time Written : 20160903031728.000000-000
Insertion Strings:
----------------------------------------------------------------------------------------------------------

Shapes.AddPicture adds only the last image - Excel VB macro for Mac

I have an excel macro, which populate images in an excel sheet from a server.
While this is straight forward for windows, for Mac, I get the images using the "curl" command, copy it over to a local folder ( if the imaage is existing), and use Shapes.AddPicture to insert the image and then delete the local image. For a single picture, this works great. But when I have to select a few columns and add multiple images, it only adds the last image. Can someone tell me why and how to fix this?
Below is the relevant code
=====================================
For Each objCell In objSelectedRange
If objCell.Value <> "" Then
UserPath = UserPath & "/" & objCell.Value & ImageType ' Add prefix and filename
ImagePath = ImageFolder & objCell.Value & ImageType
FTPpathtofile = ImagePath
scriptToCheck = "tell application " & Chr(34) & "Finder" & Chr(34) & " to do shell script " & Chr(34) & "curl " & FTPpathtofile & Chr(34)
retCode = MacScript(scriptToCheck)
str = (InStr(retCode, "404"))
If (str = 0) Then
scriptToRun = "tell application " & Chr(34) & "Finder" & Chr(34) & " to do shell script " & Chr(34) & "curl " & FTPpathtofile & " >" & UserPath & Chr(34)
MacScript (scriptToRun)
With ActiveSheet
PathtoHD = MacScript("path to startup disk as string")
localImagePath = Replace(UserPath, "/", ":")
localImagePath = PathtoHD & localImagePath
Set objImgMac = .Shapes.AddPicture(localImagePath, True, True, objCell.Left, objCell.Top, 30, 60)
If adjustCell Then
objCell.RowHeight = 78
If objCell.ColumnWidth < 12 Then
objCell.ColumnWidth = 12
End If
End If
If vAlign = "Top" Then
objCell.VerticalAlignment = xlVAlignTop
objImgMac.Top = objCell.Top + 15
objImgMac.Left = objCell.Left + 5
Else
If vAlign = "Bottom" Then
objCell.VerticalAlignment = xlVAlignBottom
objImgMac.Top = objCell.Top + 5
objImgMac.Left = objCell.Left + 5
End If
End If
End With
'delete file from the folder
DeleteFileOnMac (localImagePath)
End If
End If
Next objCell
=============================
You have
UserPath = UserPath & "/" & objCell.Value & ImageType
within your loop, but you don't seem to ever reset the value of UserPath between iterations, so it will just accumulate content.

HTA(vbs) - To do list - delete or modify array items

I'm trying to create an HTA To Do List saving locally to a text file. Every time you press submit button generates a new entry that display inside hta body and it's being saved inside the text file. I want to develop this furthermore :
delete an entry and update body/text file
modify an entry and update body/text file
put new entry on top
Any suggestions?
<html>
<head>
<HTA:APPLICATION SINGLEINSTANCE="yes" APPLICATIONNAME="To Do List">
</head>
<SCRIPT Language="VBScript">
Sub Window_OnLoad
ReadBlog
End Sub
Sub SaveData
strDel1="<"
strDel2=">"
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists("C:\Test.txt") Then
Set objFile = objFSO.OpenTextFile("C:\Test.txt", 8)
strLine = strDel1 & Time & vbTab & Date & vbTab & Title.Value & vbTab & Message.Value & strDel2
objFile.WriteLine strLine
objFile.Close
Else
Set objFile = objFSO.CreateTextFile("C:\Test.txt")
strLine = strDel1 & Time & vbTab & Date & vbTab & Title.Value & vbTab & Message.Value & strDel2
objFile.WriteLine strLine
objFile.Close
End If
ReadBlog
ClearText
End Sub
Sub ReadBlog
Const ForReading = 1, ForWriting = 2
dim sampletext, objRegExp, SearchPattern, ReplacePattern, matches
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Test.txt", ForReading)
Do Until objFile.AtEndOfStream
sampletext = objFile.ReadAll
SearchPattern = "<"
SearchPattern = SearchPattern & "(.*?)([\s\S]*?)"
SearchPattern = SearchPattern & ">"
Set objRegExp = New RegExp
objRegExp.Pattern = searchpattern ' apply the search pattern
objRegExp.Global = True ' match all instances if the serach pattern
objRegExp.IgnoreCase = True ' ignore case
Set matches = objRegExp.execute(sampletext)
If matches.Count > 0 Then ' there was at least one match to the search pattern
i=0
For Each match in matches
arrEntry = Split(Split(match.Value, "<")(1), ">")(0)
arrFields = Split(arrEntry, vbTab)
strTime = arrFields(0)
strDate = arrFields(1)
strTitle = arrFields(2)
strMessage = arrFields(3)
strHTML = strHTML & "<p>" & strTime & "</p>"
strHTML = strHTML & "<p>" & strDate & "</p>"
strHTML = strHTML & "<p>" & strTitle & "</p>"
strHTML = strHTML & "<p>" & strMessage & "</p>"
strHTML = strHTML & "<input type='button' name='Delete' value='Delete' >"& i &"<p>"
i=i+1
Next
Else ' there were no matches found
MsgBox objRegExp.Pattern & "was not found in the string"
End If
Loop
DataArea.InnerHTML = strHTML
Set objRegExp = Nothing
Set objFSO = Nothing
End Sub
Sub ClearText
Title.Value = ""
Message.Value = ""
End Sub
</SCRIPT>
<body>
<input type="text" name="Title" size="101"><p>
<textarea rows="10" cols="76" type="text" name="Message" size="25"></textarea><p>
<input type="button" value="Submit" onClick="SaveData">
<p><div id="DataArea"></div></p>
</body>
</html>
Are you particularly tied to using text files? If you used a database (such as access) you could do this quite easily (you don't have to have access installed to use an access database with an HTA either). And it would open up some other possibilities.
Incidentally, I also notice you're doing this:
strHTML = strHTML & "<p>" & strTime & "</p>"
strHTML = strHTML & "<p>" & strDate & "</p>"
strHTML = strHTML & "<p>" & strTitle & "</p>"
strHTML = strHTML & "<p>" & strMessage & "</p>"
Not a big thing, but concatenating the strings like that isn't great for performance. You'd be better off writing it all to the variable at the same time, otherwise it has to keep writing the variable to memory over and over again.
If you want to read a file with HTA you can easily do it in javaScript. Since the context changes IE allws you to directly read file on the computer or the network to wich the computer is linked to. In order to do so, you need to access the File System Object (FSO)
Full Documentation on FSO
If you are still looking to access a database you need to use the ADODB.Connection. That will allow you to connect to database localy or remotely. Altought there is not much documentation on the subject we did it at my work place. With a little imagination you can figure out how to fix it.
Documentation on the ADODB.Connnect
In this documentation the example are in VB but you can write them in JS as well.

Resources