Home > Programming > Adventures in VBScript – Including code from other files

Adventures in VBScript – Including code from other files

If you’re a VBScript hack like me, you’re probably frustrated by the inability of VBScript to include code from other files natively. Yes, you can use funky Job files etc, but nothing beats the simplicity of an all-in-one .VBS.

I’ve created innumerable “helper” scripts and classes over the years, and even wrote a tool I call “region” which selectively merges different files together to make one big (unreadable) script.

My utopia of having simple, small scripts which leveraged my 20 year programming library has not been achieved, until now.

Here you’ll find my “Include for VBS” function – surprisingly simple, but it took 20 years of thinking about it before I got around to writing it. There were two problems to solve:

1. How to read code from another file and have it available to the script

That’s the easy part – VBScript easily reads text files, and the executeglobal statement allows you to “add” code to the runtime in memory.

2. Don’t include things twice, or three times etc

Harder – as it requires the include function to track what modules it’s loaded. Since the Include function might be in a class, we need to make sure we don’t include things multiple times for multiple classes etc – it’s all to do with scope.

Thankfully the executeglobal and eval functions come to our aid again – we can use them to create variables on the fly in the global workspace which we can use to track which files we’ve loaded.

So, with those problems solved – here’s my snippit to reliably include files ONCE in your VBScripts, saving you duplicating the same code over and over again.

Sub Include(fSpec)
	' Sub to load file modules (Once!)
	' Simply call this function with the path to the vbs file you want to include, and it will be 
	' loaded into memory ONCE, even if you try to load it a number of times. 
	Dim sTemp
	On Error Resume Next
	sTemp = Eval("ICLF")
	On Error Goto 0
	If IsEmpty(sTemp) Then 
		' no currently loaded files - first Include run
		ExecuteGlobal "Dim ICLF : ICLF = 0"
	End If
	' test to see if file has already been loaded
	If InStr(1,iclf,fspec,vbTextCompare)=0 Then
		With CreateObject("Scripting.FileSystemObject")
			If .fileexists(fspec) Then
				ExecuteGlobal .openTextFile(fSpec).readAll()
				MsgBox "Include file " & fspec & " not found. Exiting",vbOKOnly+vbExclamation,"Critical Error."
			End If
		End With
		ICLF = ICLF & "|" & fspec
		' file already loaded
	End If
End Sub


Categories: Programming
  1. July 28, 2015 at 19:27

    Why would you still use Vbsript in modern day and age where PowerShell v5 is about to be released which has this functionality built in (in addition to others).

    • Simon Hunt
      July 28, 2015 at 22:21

      Because I like VBS more than powershell? Because I have a huge legacy of very reliable, robust helper classes, and because I’m not automating sysadmin tasks, I’m writing programs.

      Pretty much every language other than VBS has an include function – it doesn’t mean they are better for a particular job (or person).

      • July 28, 2015 at 22:37

        I have written VBS (WSH) scripts since Windows 2000 as well. I just don’t get trying to work around limitation of something which was last updated in 2009 (last update to WSH) when PowerShell is available. I’ll not be surprised they will pull support for VBscript in next version of Windows or something. It’s probably feels like trying to optimize batch files while WSH was already available for scripting needs. It has it’s purpose but it’s worth investing in moving to something new instead.

  2. July 28, 2015 at 22:39

    How do you “write programs” with Vbscript anyway? It’s interpreted language, so what kinds of programs do you write?

  3. Simon Hunt
    July 29, 2015 at 10:22

    I think a theological discussion on the benefits of various languages it outside the scope of this topic.

  4. Dave Morgan
    February 9, 2017 at 05:58

    I too have used vbscript over many years and have a significant library of reusable components. The lack of an include was frustrating and I solved the problem the same way you have. The most significant problem with the approach is tracing errors when they occur. Because the entire script source does not exist in a single file, errors that occur reference line numbers that cannot be easily translated to the actual source line. Other than that it works well and has saved me tons of time assembling solutions from my library of script source class modules.

    To the other point, admittedly vbscript is not a full featured developer tool and suffers from significant limitations especially on the UI front…however…outside of automating operational admin tasks vbscript can walk all over PowerShell. I see vbscript has a dumbed down flavour of MS VBA/Visual Basic with one hand tied behind its back. The power comes from the ease of use as an interpreted tool and the ability to instantiate class library methods using “CreateObject”. All of these tools have their strengths/weaknesses and if you actually use them you will understand when to pick what for a particular task. In an MS environment, between Visual Studio, VBScript, Powershell and ASP/ASP.Net there is very little you can’t accomplish from admin automation, to full blown classic client and web apps.

    • Simon Hunt
      February 10, 2017 at 13:38

      Thanks for your comments Dave – I agree for speed of implementation, VBScript is hard to beat. Re debugging though, I can recommend the excellent VBSEdit – it handles included modules admirably!

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: