{"id":67393,"date":"2006-05-04T10:02:00","date_gmt":"2006-05-04T10:02:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/05\/04\/how-can-i-query-a-text-file-and-retrieve-records-that-occurred-on-a-specific-date\/"},"modified":"2006-05-04T10:02:00","modified_gmt":"2006-05-04T10:02:00","slug":"how-can-i-query-a-text-file-and-retrieve-records-that-occurred-on-a-specific-date","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-query-a-text-file-and-retrieve-records-that-occurred-on-a-specific-date\/","title":{"rendered":"How Can I Query a Text File and Retrieve Records That Occurred on a Specific Date?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! We have tons of text files in which each line in the file represents a record or an event of some kind. How can I use a script to retrieve records or events that occurred on a specified date?<BR><BR>&#8212; TW<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, TW. You know, in your email you sort of apologized for using text files, noting that \u201cI know, I know, we should probably use a database rather than text files.\u201d Take it from us, TW: you have nothing to apologize for. If these text files do what you need them to do, then you should keep using them. Admittedly, there are times when a database might be the most appropriate tool; then again, based on the number of questions we get regarding text files it\u2019s obvious that lots of people still find the old-fashioned log file to be extremely useful. As the saying goes, if it ain\u2019t broke, don\u2019t fix it.<\/P>\n<P>The truth is, people often-times worry about things they shouldn\u2019t worry about. We get lots of letters from system administrators saying, \u201cI have a batch file that works great, but it <I>is<\/I> just a batch file. Should I convert this to a script?\u201d Well, you can if you want to, but if it works (and works great) why bother? If you\u2019re like the Scripting Guys, you have enough to do fixing things that really <I>do<\/I> need to be fixed; there\u2019s no sense going around fixing things that <I>don\u2019t<\/I> need to be fixed.<\/P>\n<P>Good point: not only is that a long, philosophical discussion, but it doesn\u2019t mention baseball even once. Wait a minute: this is supposed to be the <I>Hey, Scripting Guy!<\/I> column; somehow we\u2019ve wandered into Dr. Phil territory! <\/P>\n<P>On the other hand, Dr. Phil never (well, hardly ever) dispenses code like this:<\/P><PRE class=\"codeSample\">Const adOpenStatic = 3\nConst adLockOptimistic = 3\nConst adCmdText = &amp;H0001<\/p>\n<p>Set objConnection = CreateObject(&#8220;ADODB.Connection&#8221;)\nSet objRecordSet = CreateObject(&#8220;ADODB.Recordset&#8221;)<\/p>\n<p>strPathtoTextFile = &#8220;C:\\Scripts&#8221;<\/p>\n<p>objConnection.Open &#8220;Provider=Microsoft.Jet.OLEDB.4.0;&#8221; &amp; _\n    &#8220;Data Source=&#8221; &amp; strPathtoTextFile &amp; &#8220;;&#8221; &amp; _\n        &#8220;Extended Properties=&#8221;&#8221;text;HDR=YES;FMT=Delimited&#8221;&#8221;&#8221;<\/p>\n<p>strHireDate = #3\/1\/2006#\nstrFile = &#8220;Employees.txt&#8221;<\/p>\n<p>objRecordset.Open &#8220;Select * FROM &#8221; &amp; strFile &amp; &#8221; where HireDate = #&#8221; &amp; strHireDate &amp; &#8220;#&#8221;, _\n    objConnection, adOpenStatic, adLockOptimistic, adCmdText<\/p>\n<p>Do Until objRecordset.EOF\n    Wscript.Echo objRecordset.Fields.Item(&#8220;LastName&#8221;)\n    Wscript.Echo objRecordset.Fields.Item(&#8220;FirstName&#8221;)   \n    Wscript.Echo objRecordset.Fields.Item(&#8220;Department&#8221;)\n    Wscript.Echo objRecordset.Fields.Item(&#8220;HireDate&#8221;)   \n    objRecordset.MoveNext\nLoop\n<\/PRE>\n<P>Before we start we should point out that TW has a series of comma-separated values (CSV) files, where the first line in each file is a header row indicating the fields in the file. For example, TW has a file similar to this (note that, in order to make the example a bit easier to follow, we\u2019ve removed several fields):<\/P><PRE class=\"codeSample\">LastName,FirstName,Department,HireDate\nMyer,Ken,Finance,3\/1\/2006\nAckerman,Pilar,Finance,3\/1\/2006\nSmith,Joe,Resarch,4\/1\/2006\n<\/PRE>\n<P>Is it important that your text files be formatted like this? It\u2019s not just important, it\u2019s crucial. We\u2019re going to use database techniques to retrieve information from the file, and to do that the file needs to be delimited in some way (in this case, using the comma as the delimiter). Ideally, your files should include a header row as well. As long as your text file looks like this you\u2019re in business.<\/P>\n<TABLE id=\"END\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. What if your text file <I>doesn\u2019t<\/I> look like this? Well, in some cases you might still be able to use database techniques to query the file. For more information, take a look at our MSDN column <A href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dnclinic\/html\/scripting03092004.asp\" target=\"_blank\"><B>Much ADO About Text Files<\/B><\/A>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>We should note two things here. First, we aren\u2019t going to explain each line of code in-depth; that\u2019s because we\u2019ve already done that in the <A href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dnclinic\/html\/scripting03092004.asp\" target=\"_blank\"><B>MSDN column<\/B><\/A>. Second, don\u2019t be scared away by the cryptic nature of some of the code found in the script. As you\u2019re about to see, much of that code is boilerplate that you neither have to worry about nor modify. It\u2019s just code that needs to be there.<\/P>\n<P>The script itself starts out by defining three constants: adOpenStatic, adLockOptimistic, and adCmdText. These constants are used to configure our \u201cdatabase\u201d (text file) query. After defining the constants we create instances of the <B>ADODB.Connection<\/B> and <B>ADODB.Recordset<\/B> objects. That brings us to this block of code:<\/P><PRE class=\"codeSample\">strPathtoTextFile = &#8220;C:\\Scripts&#8221;<\/p>\n<p>objConnection.Open &#8220;Provider=Microsoft.Jet.OLEDB.4.0;&#8221; &amp; _\n    &#8220;Data Source=&#8221; &amp; strPathtoTextFile &amp; &#8220;;&#8221; &amp; _\n        &#8220;Extended Properties=&#8221;&#8221;text;HDR=YES;FMT=Delimited&#8221;&#8221;&#8221;\n<\/PRE>\n<P>As you can see, we\u2019re doing two things here. First, we assign a path to the variable strPathToTextFile. Note that this path represents the <I>folder<\/I> in which the text file can be found. It\u2019s not the path to the actual text file itself; that would be akin to C:\\Scripts\\Employees.txt. It\u2019s just the path to the folder.<\/P>\n<P>Second, we call the <B>Open<\/B> method to make an ADO (ActiveX Data Objects) connection to the folder C:\\Scripts. This is a perfect example of the boilerplate nature of this script: assuming your text file is properly formatted and assuming you\u2019ve assigned the folder path to strPathToTextFile, then you can leave this code exactly as-is; you don\u2019t need to change a thing.<\/P>\n<P>If only everything in life was that easy, huh?<\/P>\n<P>After we make a connection we then assign values to a pair of variables:<\/P><PRE class=\"codeSample\">strHireDate = #3\/1\/2006#\nstrFile = &#8220;Employees.txt&#8221;\n<\/PRE>\n<P>In this script we want to retrieve information about all the employees who were hired on March 1, 2006; consequently, we assign that date to the variable strHireDate. Why did we enclose the date in #\u2019s? That\u2019s easy: to ensure that VBScript treats the value as a date, and not as, say, an arithmetic problem (i.e., 3 divided by 1 divided by 2006). Meanwhile, we assign the name of the text file (Employees.txt) to a variable named strFile.<\/P>\n<P>What does all that mean? It means we\u2019re ready to issue our query:<\/P><PRE class=\"codeSample\">objRecordset.Open &#8220;Select * FROM &#8221; &amp; strFile &amp; &#8221; where HireDate = #&#8221; &amp; strHireDate &amp; &#8220;#&#8221;, _\n    objConnection, adOpenStatic, adLockOptimistic, adCmdText\n<\/PRE>\n<P>The query is actually pretty straightforward. One of the fields in our text file is named HireDate. How do we know that? Because that\u2019s one of the field names listed in the file\u2019s header row:<\/P><PRE class=\"codeSample\">LastName,FirstName,Department,HireDate\n<\/PRE>\n<P>When we issue our query we simply request all the records (that is, all the lines in the text file) where the HireDate field is equal to #3\/1\/2006#. Notice that we use the variable strFile (which contains the name of the text file) at the point in the query where we would typically insert a database table name:<\/P><PRE class=\"codeSample\">&#8220;Select * FROM &#8221; &amp; strFile &amp; &#8221;\n<\/PRE>\n<P>And that\u2019s basically that. Through the magic of ADO you\u2019ll get back a recordset consisting of all the records (all the lines in the text file) where the hire date is equal to 3\/1\/2006. At that point you simply walk through the recordset and echo back the values:<\/P><PRE class=\"codeSample\">Do Until objRecordset.EOF\n    Wscript.Echo objRecordset.Fields.Item(&#8220;LastName&#8221;)\n    Wscript.Echo objRecordset.Fields.Item(&#8220;FirstName&#8221;)   \n    Wscript.Echo objRecordset.Fields.Item(&#8220;Department&#8221;)\n    Wscript.Echo objRecordset.Fields.Item(&#8220;HireDate&#8221;)   \n    objRecordset.MoveNext\nLoop\n<\/PRE>\n<P>Not only do you get the same results as you would if your data was stored in a database, but you use pretty much the same scripting code as well. If this works for you, TW, then we recommend that you hang on to your text files. For obvious reasons, the Scripting Guys would never suggest that you should get rid of someone &#8211; er, <I>something<\/I> just because it isn\u2019t cool. (Not that the Scripting Guys aren\u2019t cool, mind you, but, still \u2026.)<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! We have tons of text files in which each line in the file represents a record or an event of some kind. How can I use a script to retrieve records or events that occurred on a specified date?&#8212; TW Hey, TW. You know, in your email you sort of apologized for [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[19,146,3,4,14,5],"class_list":["post-67393","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-activex-data-objects-ado","tag-databases","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! We have tons of text files in which each line in the file represents a record or an event of some kind. How can I use a script to retrieve records or events that occurred on a specified date?&#8212; TW Hey, TW. You know, in your email you sort of apologized for [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67393","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=67393"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67393\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=67393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=67393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=67393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}