{"id":68523,"date":"2005-11-15T10:27:00","date_gmt":"2005-11-15T10:27:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/11\/15\/how-can-i-use-ado-to-read-a-text-file-where-all-the-data-is-on-a-single-line\/"},"modified":"2005-11-15T10:27:00","modified_gmt":"2005-11-15T10:27:00","slug":"how-can-i-use-ado-to-read-a-text-file-where-all-the-data-is-on-a-single-line","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-use-ado-to-read-a-text-file-where-all-the-data-is-on-a-single-line\/","title":{"rendered":"How Can I Use ADO to Read a Text File Where All the Data is on a Single Line?"},"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! I have a fixed-width text file which includes first name (6 characters), last name (13 characters), and department (9 characters) all on a single line. How do I read that using ADO?<BR><BR>&#8212; DW<\/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, DW. Well, to be perfectly honest, we don\u2019t think you <I>can<\/I> read a file like this using ADO (ActiveX Data Objects). ADO is a fantastic way to interact with text files (for more information, see the article <A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms974559.aspx\" target=\"_blank\"><B>Much ADO About Text Files<\/B><\/A>), but &#8211; really &#8211; ADO is a bit of a prima donna: everything has to be set up just right or ADO will refuse to work. (Unlike the Scripting Guys, who refuse to work even if everything <I>is<\/I> set up just right.) As a database technology, ADO requires &#8211; to steal a term from the XML world &#8211; a \u201cwell-formed\u201d database; it\u2019s simply not equipped to take a file like yours and <I>make<\/I> a database out of it. (In this case, by chopping your huge line into individual records.)<\/P>\n<P>But that\u2019s all right; after all, we can use good old, reliable VBScript to create a well-formed database. What we\u2019ll do today is show you how you can quickly and easily carve your huge string of data into individual records. We\u2019ll do that simply by echoing those individual records (i.e., individual records in the text file) back to the screen. However, you could easily write those lines to another text file and then use ADO to read in that second text file. We\u2019re just going to help you get started, then let you take it from there.<\/P>\n<P>To begin with, we\u2019re assuming you have a text file that looks something like this, with field names and a couple of records all contained on a single line:<\/P><PRE class=\"codeSample\">First Last         Dept     Ken   Meyer        Finance  Pilar Ackerman     HR\n<\/PRE>\n<P>What we want to end up with is something that looks more like this:<\/P><PRE class=\"codeSample\">First Last         Dept     \nKen   Meyer        Finance  \nPilar Ackerman     HR\n<\/PRE>\n<P>Is that possible? Of course it is:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)<\/p>\n<p>strContents = objFile.ReadAll\nobjFile.Close<\/p>\n<p>i = False<\/p>\n<p>Do Until i = True \n    intLength = Len(strContents)\n    If intLength &lt; 28 Then\n        Exit Do\n    End If\n    strLines = strLines &amp; Left(strContents, 28) &amp; vbCrLf\n    strContents = Right(strContents, intLength &#8211; 28)\nLoop<\/p>\n<p>Wscript.Echo strLines\n<\/PRE>\n<P>We start out by defining a constant named ForReading and set the value of that constant to 1; we\u2019ll use that to open our text file for reading. <\/P>\n<TABLE id=\"EQD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B> You know how your mother would <I>always<\/I> tell you to put your hood up, or to look both ways when crossing the street? Well, we Scripting Guys <I>always<\/I> tell you that you can\u2019t open a text file without specifying how you want to open that text file: for reading, for writing, for appending. And you can only do one operation at a time: you can\u2019t open a text file for both reading <I>and<\/I> writing. Hence the need for the constant ForReading.<\/P>\n<P>Oh: and put your hood up, too. It\u2019s cold outside.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Next we create an instance of the <B>FileSystemObject<\/B> and use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Test.txt. We call the <B>ReadAll<\/B> method in order to read the entire contents of that file into the variable strContents, then use the <B>Close<\/B> method to close the file.<\/P>\n<P>After that we have this odd little line of code:<\/P><PRE class=\"codeSample\">i = False\n<\/PRE>\n<P>What we\u2019re going to do in a second is set up a Do loop that enables us to read the contents of the file (well, OK, the value of the variable strContents) in 28-character increments. Why 28 characters? Well, we have 6 characters in each record reserved for the first name, 13 characters set aside for the last name, and 9 characters allotted for the department. Thus:<\/P><PRE class=\"codeSample\">6 + 13 + 9 = 28\n<\/PRE>\n<P>In order to keep our loop going until we\u2019ve read through the entire file, we set the variable <I>i<\/I> to False, then tell our loop to keep going until <I>i<\/I> is equal to True:<\/P><PRE class=\"codeSample\">Do Until i = True\n<\/PRE>\n<P>As it turns out, <I>i<\/I> never <I>will<\/I> equal True, but don\u2019t worry: we\u2019ll still be able to get out of the loop, and we\u2019ll show you that Houdini-like feat in a moment.<\/P>\n<P>Inside the loop we first use the <B>Len<\/B> function to determine the number of characters in the string strContents (with our sample file, and counting the header line as a record, that should be 28 characters per record times 3 records, or 84). We then have this little block of code:<\/P><PRE class=\"codeSample\">If intLength &lt; 28 Then\n    Exit Do\nEnd If\n<\/PRE>\n<P>What we\u2019re doing here is checking to see if the length of our string is less than 28 characters. If it is, then we must have reached the end of the file. Therefore, we use the <B>Exit Do<\/B> command to exit the loop. (And <I>that\u2019s<\/I> how the amazing Scripting Guys managed to escape the clutches of the never-ending Do loop!)<\/P>\n<P>Assuming the length is 28 characters or more, we then execute this line of code:<\/P><PRE class=\"codeSample\">strLines = strLines &amp; Left(strContents, 28) &amp; vbCrLf\n<\/PRE>\n<P>Here we\u2019re creating a new string &#8211; strLines &#8211; that divides the contents of our text file into separate records, each record consisting of 28 characters plus a carriage return-linefeed (<B>vbCrLf<\/B>). To do that, we simply combine the current contents of strLine with the first 28 characters in the string (that\u2019s what the <B>Left<\/B> function does) and the VBScript constant vbCrLf. The first time through the loop strLines will look like this:<\/P><PRE class=\"codeSample\">First Last         Dept\n<\/PRE>\n<P>See how that works? <\/P>\n<P>As soon as our first line (that is, our first record) is safely tucked away in the variable strLines, we then need to delete that information from strContents. That\u2019s what we do here:<\/P><PRE class=\"codeSample\">strContents = Right(strContents, intLength &#8211; 28)\n<\/PRE>\n<P>This time we\u2019re using the <B>Right<\/B> function to take <I>x<\/I> number of characters from the end of the string, working our way backwards. What, exactly, do we mean by <I>x<\/I> number of characters? To calculate <I>x<\/I> we take the length of strContents (84) and subtract 28 (the length of an individual record). That leaves us with 56 (84 &#8211; 28 = 56) so we start at the end of the string and count back 56 characters. That means, the first time through the loop, we\u2019ll end up with this:<\/P><PRE class=\"codeSample\">Ken   Meyer        Finance  Pilar Ackerman     HR\n<\/PRE>\n<TABLE id=\"ETG\" 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>. Yes, there are other ways we could do this, some of which might save you a line or two of code. However, we thought this approach was the easiest.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>As you can see, all we\u2019ve done is remove the first record. We\u2019re now ready to go back through the loop and repeat the process. This time, of course, the length of strContents will be 56; that\u2019s because we just eliminated 28 characters. In turn, that means we\u2019ll end up pulling out this data and adding it to the variable strLines: <\/P><PRE class=\"codeSample\">Ken   Meyer        Finance\n<\/PRE>\n<P>We continue this process until we run out of characters in the variable strContents. At that point we simply echo back the values of strLines:<\/P><PRE class=\"codeSample\">First Last         Dept     \nKen   Meyer        Finance  \nPilar Ackerman     HR\n<\/PRE>\n<P>If that\u2019s not a well-formed database, well, we don\u2019t know what is.<\/P>\n<P>Like we said, if you wanted to you could save the data to a text file and read it using ADO, or you could use simply use VBScript\u2019s <A href=\"http:\/\/null\/technet\/scriptcenter\/guide\/sas_vbs_vcgg.mspx\" target=\"_blank\"><B>string-handling functions<\/B><\/A> to divvy each line into individual records. We\u2019ll leave that up to you.<\/P>\n<P>Oh, and one other thing before we go: didn\u2019t we tell you to put your hood up?<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a fixed-width text file which includes first name (6 characters), last name (13 characters), and department (9 characters) all on a single line. How do I read that using ADO?&#8212; DW Hey, DW. Well, to be perfectly honest, we don\u2019t think you can read a file like this using ADO [&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-68523","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! I have a fixed-width text file which includes first name (6 characters), last name (13 characters), and department (9 characters) all on a single line. How do I read that using ADO?&#8212; DW Hey, DW. Well, to be perfectly honest, we don\u2019t think you can read a file like this using ADO [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68523","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=68523"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68523\/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=68523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=68523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=68523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}