{"id":55623,"date":"2008-05-07T01:33:00","date_gmt":"2008-05-07T01:33:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/05\/07\/hey-scripting-guy-how-can-i-modify-a-csv-file-and-then-import-that-file-into-microsoft-excel\/"},"modified":"2008-05-07T01:33:00","modified_gmt":"2008-05-07T01:33:00","slug":"hey-scripting-guy-how-can-i-modify-a-csv-file-and-then-import-that-file-into-microsoft-excel","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-modify-a-csv-file-and-then-import-that-file-into-microsoft-excel\/","title":{"rendered":"Hey, Scripting Guy! How Can I Modify a .CSV File and Then Import That File into Microsoft Excel?"},"content":{"rendered":"<p><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hey, Scripting Guy! I have a comma-separated values file that I need to import into Excel. However, before I do that I need to do some arithmetic and then add an additional field to the CSV file. On top of that, when I import this file I need to format this new field as a date-time value. How can I do that?<br \/>&#8212; R<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><img decoding=\"async\" class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\" \/><\/a> <\/p>\n<p>Hey, R. Well, by now most of you have probably heard that Microsoft is no longer interested in buying Yahoo! Although we offered Yahoo! a deal worth around $50 billion, that proposal was rejected; Yahoo! wanted another $5 billion or so. (Hey, don\u2019t we <i>all<\/i> want another $5 billion or so?) At any rate, Microsoft CEO Steve Ballmer decided that $55 billion was more than Yahoo! was worth, and he called the deal off.<\/p>\n<p>For both Yahoo! and Microsoft life goes on; today is simply business as usual. For Yahoo! stockholders, however, it\u2019s a different story: after all, no sooner did Microsoft announce that it had called off the deal then Yahoo! shareholders saw their stock value nosedive by 20 percent. The Scripting Guys hate to see anybody suffer a financial setback like that. Therefore, as a public service, the Scripting Guys would like to announce that we are not walking away from the deal that <i>we<\/i> proposed a <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/apr08\/hey0409.mspx\"><b>couple weeks ago<\/b><\/a>: in return for complete and total ownership of the company, we will give every Yahoo! stockholder their very own <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/bobbles.mspx\"><b>Dr. Scripto bobblehead doll<\/b><\/a>. (<i>Ed<\/i><i>itor\u2019s Note: Bobblehead doll<\/i><i>s<\/i><i> not included.<\/i>) In fact, not only are we not walking away from that deal, but as a way to sweeten the offer a little, Scripting Guy Peter Costantini has agreed to divvy his salary up among each and every Yahoo! shareholder.<\/p>\n<table class=\"dataTable\" id=\"EYD\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p><b>Note<\/b>. Did Scripting Guy Peter Costantini <i>really<\/i> agree to divvy his salary up among each and every Yahoo! shareholder? Well, if you want to get picky about it, no, he didn\u2019t. But that\u2019s only because Peter is an extremely busy guy, and we didn\u2019t want to bother him. And seeing as how he didn\u2019t actually say \u201cno,\u201d well, that must mean that his answer is \u201cyes.\u201d<\/p>\n<p>In case you\u2019re wondering, we don\u2019t know what Peter\u2019s annual salary is. We know how much Peter is <i>worth<\/i>, but that\u2019s a different story.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>But wait; that\u2019s not all. In addition to a bobblehead doll and a cut of Peter Costantini\u2019s salary, each and every Yahoo! shareholder will also receive a script that can modify a CSV file, import that file into Microsoft Excel, and then apply a date-time format to one of the columns. That\u2019s a script that, by itself, has an estimated street value of $62.3 billion, well above the Yahoo! asking price of $55 billion.<\/p>\n<p>What\u2019s that? You don\u2019t think the Scripting Guys even <i>have<\/i> a script that can do all? Well, just feast your eyes on <i>this<\/i> baby:<\/p>\n<pre class=\"codeSample\">Const ForReading = 1\nConst ForWriting = 2\n\nSet objFSO = CreateObject(\"Scripting.FileSystemObject\")\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.csv\", ForReading)\n\nDo Until objFile.AtEndOfStream\n    strLine = objFile.ReadLine\n    arrItems = Split(strLine, \",\")\n\n    intDateValue = arrItems(1) - 1530000\n    intItems = Ubound(arrItems)\n    ReDim Preserve arrItems(intItems + 1)\n    If intDateValue &gt; 0 Then\n        arrItems(intItems + 1) = intDateValue\n    Else\n        arrItems(intItems + 1) = \"\"\n    End If\n    strNewLine = Join (arrItems, \",\")\n    strNewText = strNewText &amp; strNewLine &amp; vbCrLf\n\nLoop\n\nobjFile.Close\n\nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.csv\", ForWriting)\nobjFile.Write strNewText\nobjFile.Close\n\nSet objExcel = CreateObject(\"Excel.Application\")\nobjExcel.Visible = True\n\nSet objWorkbook = objExcel.Workbooks.Open(\"C:\\Scripts\\Test.csv\")\nSet objRange = objExcel.Cells(1, 6)\nSet objRange = objRange.EntireColumn\n\nobjRange.NumberFormat = \"m\/d\/yyyy hh:mm:ss AM\/PM\"\n<\/pre>\n<p>There appears to be a question in the back: can we explain how this script works? Not really; after all, we\u2019re already losing a <i>lot<\/i> of money as it is by giving the code away. But what the heck; if it will help cinch the deal and get us ownership of Yahoo!, well, then we\u2019ll do it.<\/p>\n<p>As you can see, the script starts out the same way most $62 billion scripts start out: by defining a pair of constants (ForReading and ForWriting), constants we\u2019ll use when we go to open our .CSV file. In fact, we\u2019re going to use one of those constants (ForReading) right now; after we create an instance of the <b>Scripting.FileSystem<\/b><b>Object<\/b> we use this line of code to open the file C:\\Scripts\\Test.csv for reading:<\/p>\n<pre class=\"codeSample\">Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.csv\", ForReading)\n<\/pre>\n<p>Ah, good question: what <i>does<\/i> Test.csv look like? Well, as it turns out, it looks something like this:<\/p>\n<pre class=\"codeSample\">200Printer1,-2000000,3600,text,tree\n201kmille5lt1,1570587,1200,text,leaf\n201Printer1,1570761,3600,text,leaf\n201SShrimpWS,1570587,1200,text,leaf\n202Check1,1570454,3600,text,fruit\n202jgrovelt,-2000000,1200,text,fruit\n202LWtextLKE1WS,1570588,1200,text,fruit\n202Printer0,1570732,3600,text,fruit\n202Printer1,1570871,3600,text,fruit\n<\/pre>\n<p>But it\u2019s not going to look like this for long; before we import this file into Excel we need to extract the second field in each line (in line 1, that\u2019s the value -2000000) and then subtract 1530000 from that number. Believe it or not, if that number is positive (greater than 0) then it can be converted to a date-time value in Excel. That means that, if the number <i>is<\/i> positive, then we\u2019ll tack that value onto the end of the line in the text file; if the value is negative then we\u2019ll add an empty string (\u201c\u201d) to the end of the line.<\/p>\n<p>So how exactly will we do all that? Well, to begin with, we set up a Do Until loop that runs until the file\u2019s <b>AtEndOfStream<\/b> property is True; in other words, we\u2019ll keep reading until there\u2019s nothing left to read. Inside that loop we use the <b>ReadLine<\/b> method to read the first line in the text file, then use VBScript\u2019s <b>Split<\/b> function to split that value (splitting on the comma) into a mini-array named arrItems:<\/p>\n<pre class=\"codeSample\">arrItems = Split(strLine, \",\")\n<\/pre>\n<p>For those of you scoring at home, that makes arrItems equal to this:<\/p>\n<pre class=\"codeSample\">200Printer1\n-2000000\n3600\nText\ntree\n<\/pre>\n<p>Why do we bother splitting our line of text into an array? Well, here\u2019s one reason: that makes it very easy to grab the value of the second field in the line (<b>arrItems(1)<\/b>) and then subtract 1530000 from it, something we do with this line of code:<\/p>\n<pre class=\"codeSample\">intDateValue = arrItems(1) - 1530000\n<\/pre>\n<p>In turn, that brings us to these two lines of code:<\/p>\n<pre class=\"codeSample\">intItems = Ubound(arrItems)\nReDim Preserve arrItems(intItems + 1)\n<\/pre>\n<p>As you know, we just grabbed the first line in our text file and converted it to an array. We now need to add an additional field to the end of that line; in effect, that means we need to add a new item to the array arrItems. How are we going to do that? Well, first we need to determine how many items are currently in the array; that\u2019s what the <b>Ubound<\/b> function tells us. We then use the <b>ReDim Preserve<\/b> statement to redimension the array, setting the new size to the number of items currently in the array (intItems) plus 1.<\/p>\n<p>Now we\u2019re ready to add a new item to the array:<\/p>\n<pre class=\"codeSample\">If intDateValue &gt; 0 Then\n    arrItems(intItems + 1) = intDateValue\nElse\n    arrItems(intItems + 1) = \"\"\nEnd If\n<\/pre>\n<p>All we\u2019re doing here is checking to see if the value of the variable intDateValue is greater than 0. If it is, we then set the value of our new array item (<b>arrItems(intItems + 1)<\/b>) to, well, the value of intDateValue. If intDateValue <i>isn\u2019t<\/i> greater than 0 then we set the value of this new array items to an empty string.<\/p>\n<p>And you\u2019re right: this <i>isn\u2019t<\/i> particularly sophisticated. But what do expect for a measly $62 billion?<\/p>\n<p>At this point we\u2019re ready to start reversing our steps, sort of. Having started things off by splitting a line of text into an array, we\u2019re now going to use the <b>Join<\/b> method to combine all the items in the array into a single, comma-separated string value:<\/p>\n<pre class=\"codeSample\">strNewLine = Join (arrItems, \",\")\n<\/pre>\n<table class=\"dataTable\" id=\"EAH\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. Like we said, though, we aren\u2019t <i>really<\/i> going backwards and undoing what we just did. After all, strNewLine, our new line of text, <i>does<\/i> include the additional array item that we just added.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>After creating the new string value we then add this value (plus a carriage return-linefeed, the VBScript constant <b>vbCrLf<\/b>) to a variable named strNewText:<\/p>\n<pre class=\"codeSample\">strNewText = strNewText &amp; strNewLine &amp; vbCrLf\n<\/pre>\n<p>And then it\u2019s back to the top of the loop, where we repeat the process with the next line in the text file.<\/p>\n<p>After we\u2019ve read and processed each line in the text file we use the <b>Close<\/b> method to close Test.csv, then immediately reopen the file, this time for writing:<\/p>\n<pre class=\"codeSample\">Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.csv\", ForWriting)\n<\/pre>\n<table class=\"dataTable\" id=\"E5H\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. Yes, we know. But the FileSystemObject won\u2019t let you simultaneously open a file for both reading and writing; it has to be one or the other.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>With Test.csv reopened we use the <b>Write<\/b> method to replace the existing contents with the value of the variable strNewText. And then we once more close Test.csv.<\/p>\n<p>Now it\u2019s time to open \u2013 and format \u2013 this file in Excel. To do that, we first create an instance of the <b>Excel.Application<\/b> object, then set the value of the <b>Visible<\/b> property to True; that gives us a running instance of Excel that we can see on screen. We then use the following line of code, and the <b>Open<\/b> method, to open our .CSV file:<\/p>\n<pre class=\"codeSample\">Set objWorkbook = objExcel.Workbooks.Open(\"C:\\Scripts\\Test.csv\")\n<\/pre>\n<p>The pre-formatted version of this spreadsheet is going to look like this:<\/p>\n<p><img decoding=\"async\" height=\"311\" alt=\"Microsoft Excel\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/csv1.jpg\" width=\"450\" border=\"0\" \/> <\/p>\n<p>What do we do next? Well, first we execute these two lines of code:<\/p>\n<pre class=\"codeSample\">Set objRange = objExcel.Cells(1, 6)\nSet objRange = objRange.EntireColumn\n<\/pre>\n<p>In line 1 we\u2019re simply creating an instance of the Excel <b>Range<\/b> object, a range that encompasses cell F1 (row 1, column 6). In line 2 when then use the <b>EntireColumn<\/b> method to extend that range to take in all of column F.<\/p>\n<p>And once <i>that\u2019s<\/i> done we can reformat all the cells in the range using the following line of code:<\/p>\n<pre class=\"codeSample\">objRange.NumberFormat = \"m\/d\/yyyy hh:mm:ss AM\/PM\"\n<\/pre>\n<table class=\"dataTable\" id=\"ERBAC\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p><b>Note<\/b>. For more information on changing the format of a cell see this classic <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/nov06\/hey1108.mspx\"><b>Hey, Scripting Guy!<\/b><\/a> column.<\/p>\n<p>Good point; the word \u201cclassic\u201d <i>is<\/i> a bit redundant, isn\u2019t it?<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>What\u2019s our spreadsheet going to look like now? It\u2019s going to look like this:<\/p>\n<p><img decoding=\"async\" height=\"311\" alt=\"Microsoft Excel\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/csv2.jpg\" width=\"450\" border=\"0\" \/> <\/p>\n<p>Not only did we get the spreadsheet we wanted, but we saved ourselves $62 billion in the process. All in all, not a bad day\u2019s work.<\/p>\n<p>Incidentally, a lot of you might be thinking, \u201cGee, $55 billion is a lot of money; I wonder what Yahoo! makes in order to be worth that much money.\u201d If that\u2019s what you\u2019re thinking, well, you simply don\u2019t understand how the new economy works. No one actually <i>makes<\/i> anything any more; that\u2019s the old-fashioned way of earning a living. Today businesses exist for the sole purpose of selling ads to other businesses, often times ads that encourage you to visit this other business\u2019 Web site. And what can you buy when you visit these other Web sites? Nothing; those sites also exists solely for the purpose of selling advertisements. That\u2019s the beauty of the new economy.<\/p>\n<p>What\u2019s that? How\u2019s the new economy doing these days? Well, OK, we aren\u2019t saying that it hasn\u2019t hit a rough spot or two. But those will get smoothed over as soon as we sell a few more ads.<\/p>\n<p>As for all you Yahoo! shareholders, well, you know how to get hold of us. We\u2019ll be waiting to hear from you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a comma-separated values file that I need to import into Excel. However, before I do that I need to do some arithmetic and then add an additional field to the CSV file. On top of that, when I import this file I need to format this new field as a [&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":[169,48,49,3,4,5],"class_list":["post-55623","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-csv-and-other-delimited-files","tag-microsoft-excel","tag-office","tag-scripting-guy","tag-scripting-techniques","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have a comma-separated values file that I need to import into Excel. However, before I do that I need to do some arithmetic and then add an additional field to the CSV file. On top of that, when I import this file I need to format this new field as a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55623","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=55623"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55623\/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=55623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}