{"id":69,"date":"2011-10-10T16:50:38","date_gmt":"2011-10-10T16:50:38","guid":{"rendered":"http:\/\/www.edcortes.ph\/?p=163"},"modified":"2021-07-11T08:00:02","modified_gmt":"2021-07-11T08:00:02","slug":"getting-started-with-vba-in-excel-2010-part-3","status":"publish","type":"post","link":"https:\/\/emcortes.com\/?p=69","title":{"rendered":"Getting Started with VBA in Excel 2010 (Part 3)"},"content":{"rendered":"<div id=\"section346\">\n<p>Suppose that you have a workbook that contains lists on a large number of worksheets and that you want to change the name of each worksheet to match the heading of the list on that worksheet. Not every worksheet has a list on it, but if it does, the heading is in cell B1, and if it does not, cell B1 is blank. The names of worksheets without lists should be left alone.<\/p>\n<p>Ordinarily, this could be a complex task that involves looking at each worksheet to see if it has a list, copying the name if it does, clicking the worksheet tab, and then pasting in the new name. Instead of performing all of those steps manually, use Excel VBA to rename the sheets automatically.<\/p>\n<h4>Learning about Objects<\/h4>\n<div>\n<p>The first step is to find out how to manipulate the particular objects that you need to work with to accomplish your task; for example, worksheets, worksheet names, cells, and cell contents. In Excel, there are at least two ways to approach the problem:<\/p>\n<ul>\n<li>Go directly to the Object Model Reference.<\/li>\n<li>Record some of the actions that you want to automate, see how the recorded code manipulates the objects, and then go to the Object Model Reference for more information.<\/li>\n<\/ul>\n<p>Opinions vary on which approach is preferable, but for now, try using the Macro Recorder first.<\/p>\n<h4>Using the Macro Recorder<\/h4>\n<div>\n<p>Sometimes a simple recorded macro is all you need; in these cases, you do not even have to look at the code. More often, recording alone is not enough. Instead, it is a starting point in the following process.<\/p>\n<h3>To use the Macro Recorder as a starting point to your solution<\/h3>\n<div>\n<ol>\n<li>Record the actions that you want to code.<\/li>\n<li>Review the code and find the lines that perform those actions.<\/li>\n<li>Delete the rest of the code.<\/li>\n<li>Modify the recorded code.<\/li>\n<li>Add variables, control structures, and other code that the Macro Recorder cannot record.<\/li>\n<\/ol>\n<\/div>\n<p>Begin your investigation by recording a macro that renames a worksheet to <strong>New Name<\/strong>. You can then use the recorded macro to develop your own macro that renames multiple worksheets based on their contents.<\/p>\n<h3>To record a macro that renames a worksheet<\/h3>\n<div>\n<ol>\n<li>Click <strong>Record Macro<\/strong> on the <strong>Developer<\/strong> tab.<\/li>\n<li>Name the macro <strong>RenameWorksheets<\/strong>, rename Sheet1 to <strong>New Name<\/strong>, and click <strong>Stop Recording<\/strong>.<\/li>\n<li>Go to the <strong>Developer<\/strong> or <strong>View<\/strong> tab, click the <strong>Macros<\/strong> button, and choose <strong>Edit<\/strong> to open the Visual Basic Editor.<\/li>\n<\/ol>\n<\/div>\n<p>The code in the Visual Basic Editor should look similar to the following.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_f832d926-4402-4b8b-ac92-7d57b55538cc\" dir=\"ltr\">\n<div>\n<pre>Sub RenameWorksheets()\r\n\u2019\r\n\u2019 RenameWorksheets Macro\r\n\u2019\r\n\u2019\r\n    Sheets(\"Sheet1\").Select\r\n    Sheets(\"Sheet1\").Name = \"New Name\"\r\nEnd Sub<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>The first four lines after the<strong> Sub<\/strong> line are comments. Any line that begins with an apostrophe is a comment and has no effect on what the macro does. The main uses for comments are the following:<\/p>\n<ul>\n<li>To make the code easier to understand, not just for you, but for anyone else who might need to modify the code later.<\/li>\n<li>To temporarily disable a line of code (called <em>commenting it out<\/em>).<\/li>\n<\/ul>\n<p>The four comments in this recorded macro serve neither purpose, so delete them.<\/p>\n<p>The next line uses the <strong>Select<\/strong> method to select the Sheet1 member of the <strong>Sheets<\/strong> collection object. In VBA code, it is not generally necessary to select objects before manipulating them, even though that is what the Macro Recorder does. In other words, this line of code is redundant, so you can delete it as well.<\/p>\n<p>The last line of the recorded macro modifies the Name Property of the <strong>Sheet1<\/strong> member of the <strong>Sheets<\/strong> collection. This is the line to keep.<\/p>\n<p>After you make your changes, the recorded code should now look like the following.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_dd1d2767-ef4a-4339-a278-5293f706b988\" dir=\"ltr\">\n<div>\n<pre>Sub RenameWorksheets()\r\n    Sheets(\"Sheet1\").Name = \"New Name\"\r\nEnd Sub<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Manually change the sheet called New Name back to Sheet1, then run the macro. The name should change back to New Name.<\/p>\n<\/div>\n<h1>\u00a0<\/h1>\n<h3>Modifying the Recorded Code<\/h3>\n<div id=\"section488\">\n<p>Now it is time to research the <strong>Sheets<\/strong> collection that the Macro Recorder used. The Sheets topic in the Object Model Reference includes the following text.<\/p>\n<p>&#8220;The <strong>Sheets<\/strong> collection can contain <strong>Chart<\/strong> or <strong>Worksheet<\/strong> objects. If you need to work with sheets of only one type, see the object topic for that sheet type.&#8221;<\/p>\n<p>You are only working with <strong>Worksheets<\/strong>, so change the code to the following.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_9a55538f-a497-43d4-94a7-15161ada0674\" dir=\"ltr\">\n<div>\n<pre>Sub RenameWorksheets()\r\n    Worksheets(\"Sheet1\").Name = \"New Name\"\r\nEnd Sub<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4>Looping<\/h4>\n<div>One limitation of the code up to this point is that it only makes a change to one worksheet. You could add another line for each worksheet that you want to rename, but what if you do not know how many worksheets there are, or what their current names are? You need a way to apply some rule <em>for each<\/em>sheet in the workbook.<br \/>\nVBA has a construction called a For Each loop that is ideal. The For Each loop examines each item in a collection object such as <strong>Worksheets<\/strong> and can be used to take an action (like change a name) to some or all of those items.<\/p>\n<p>For more information about the For Each loop, see the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee441138.aspx\">VBA Language Reference<\/a>. Click &#8220;Visual Basic Conceptual Topics&#8221;, then &#8220;Using For Each&#8230;Next Statements&#8221;. Also, be aware that the VBA Language Reference, like the Object Model Reference, will amply repay the time that you spend browsing it, and is an excellent place to look for ideas if you get stuck working on code.<\/p>\n<p>Using the third example in the &#8220;Using For Each&#8230;Next Statements&#8221; topic, edit the macro so that it looks similar to the following code.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_4cad931e-7eda-4bf7-9580-4c7f98d3a572\" dir=\"ltr\">\n<div>\n<pre>Sub RenameWorksheets()\r\nFor Each myWorksheet In Worksheets\r\n    myWorksheet.Name = \"New Name\"\r\nNext\r\nEnd Sub<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><code>myWorksheet<\/code> is a variable; that is, what it represents varies. In this case, the <code>myWorksheet<\/code> variable successively represents each worksheet in the <strong>Worksheets<\/strong> collection. You do not have to use <code>myWorksheet<\/code>; you could use &#8220;x&#8221;, &#8220;ws&#8221;, &#8220;WorksheetToRenameAfterTheContentsOfCellB1&#8221;, or (with a few restrictions) almost any name that you want. A good rule of thumb is to use variable names that are long enough to remind you of what the variable stands for, but not so long as to clutter the code.<\/p>\n<p>If you run the macro in its current state, it produces an error because Excel requires each worksheet in a workbook to have a unique name, but the following line instructs Excel to give every worksheet the same name.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_18ff7f1d-3598-493c-bcfa-c4f52ee8f4c4\" dir=\"ltr\">\n<div>\n<pre>    myWorksheet.Name = \"New Name\"<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>To correct the line so that you can verify that the For Each loop works, change the line to the following.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_b78de439-b5a7-4f11-8885-85310626edfc\" dir=\"ltr\">\n<div>\n<pre>    myWorksheet.Name = myWorksheet.Name &amp; \"-changed\"<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Instead of trying to give each worksheet the same name, this line changes the current name of each worksheet (<code>myWorksheet.Name<\/code>) to the current name with &#8220;-changed&#8221; appended to it.<\/p>\n<\/div>\n<h4>Useful Renaming<\/h4>\n<div>\n<p>The macro is getting close to something that might actually solve the problem at hand. What you need now is a way to take information from the worksheets themselves\u2014specifically from cell B1 on each worksheet\u2014and put that information into the names of the worksheets.<\/p>\n<p>This time, instead of using the Macro Recorder to find out how to refer to a cell, take a guess and see if using the Cell object will work. It is a good guess, but if you open the Object Model Reference and search for the Cell object, you find that there is no Cell object! There is a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb210108.aspx\">CellFormat object<\/a> though.<\/p>\n<p>The <strong>CellFormat<\/strong> object topic includes the following code in the first code sample.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_a992301f-05ff-467b-a018-76eb9c8b6a0e\" dir=\"ltr\">\n<div>\n<pre>    \u2019 Set the interior of cell A1 to yellow.\r\n    Range(\"A1\").Select<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>It turns out that you use <strong>Range<\/strong> to specify a range of cells or just one individual cell. Again, you do not need the <strong>.Select<\/strong> portion, but you do need to find out how to refer to the contents of the <strong>Range<\/strong> object, as opposed to the <strong>Range<\/strong> object itself. If you go to the <strong>Range<\/strong> object topic, you can read that <strong>Range<\/strong> has both <strong>Methods<\/strong> and <strong>Properties<\/strong>. The contents of a <strong>Range<\/strong> is a thing, not an action, so it would probably be a <strong>Property<\/strong>. If you scan down through the list, you can see the <strong>Value<\/strong> property. So, try the following.<\/p>\n<div><script type=\"text\/javascript\" src=\"\/Areas\/Global\/Content\/CodeSnippet.js\"><\/script><\/p>\n<div>\n<div dir=\"ltr\"><a>VB<\/a><\/div>\n<\/div>\n<div>\n<div id=\"CodeSnippetContainerCode_d118963f-502f-4e7d-842a-b35fa46daf77\" dir=\"ltr\">\n<div>\n<pre>Sub RenameWorksheets()\r\nFor Each myWorksheet In Worksheets\r\n    myWorksheet.Name = myWorksheet.Range(\"B1\").Value\r\nNext\r\nEnd Sub<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>You get an error if you run this on a workbook that contains worksheets where B1 is empty, because an empty <strong>Range<\/strong> has a Value of &#8220;&#8221; (an empty text string), which is not a legal worksheet name. It is about time to create some sample data anyway. Make the three sheets in the workbook look similar to the figure below, and then run the macro.<\/p>\n<p>Source: <a href=\"http:\/\/msdn.microsoft.com\/\">http:\/\/msdn.microsoft.com<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Suppose that you have a workbook that contains lists on a large number of worksheets and that you want to change the name of each worksheet to match the heading of the list on that worksheet. Not every worksheet has a list on it, but if it does, the heading is in cell B1, and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,4],"tags":[],"class_list":["post-69","post","type-post","status-publish","format-standard","hentry","category-excel","category-programming-notes"],"_links":{"self":[{"href":"https:\/\/emcortes.com\/index.php?rest_route=\/wp\/v2\/posts\/69","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/emcortes.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/emcortes.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/emcortes.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/emcortes.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=69"}],"version-history":[{"count":1,"href":"https:\/\/emcortes.com\/index.php?rest_route=\/wp\/v2\/posts\/69\/revisions"}],"predecessor-version":[{"id":341,"href":"https:\/\/emcortes.com\/index.php?rest_route=\/wp\/v2\/posts\/69\/revisions\/341"}],"wp:attachment":[{"href":"https:\/\/emcortes.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=69"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/emcortes.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=69"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/emcortes.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=69"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}