I have an Excel sheet which is used for bug-tracking. Each client has their own .xlsx and each application for that client has its own sheet within the .xlsx. So multiple Excel files with multiple sheets, all in the same format.
All sheets have the same headings and some columns have data validation and conditional formatting. Occasionally, however, the layout/headings or values allowed in data-validated cells, etc. must change and I have to go through each sheet and manually make the changes.
Is it possible to have a master sheet from which other sheets will inherit headings and heading styles with all cells under particular headings having data validation and conditional formatting?
(Before this is suggested, I used to simply put everything in one sheet and use filters to show a particular client/application, but this became impractical when sharing and versioning the sheets with multiple people)
The term you are looking for is a template. You create the template and give that to your 'clients' to track bugs. If you make an update to the template and give it to the client, they can just copy/paste data into the new form.
In my opinion, you're going about this the wrong way. Excel is a spreadsheet programme, while it CAN be used as a 'list' of sorts, it is a poor choice for bug tracking. If you're stuck on Office applications, use an Access database or something that can actually give you a 'front end display' separate from the 'back end data'. There are many free bug tracking software programmes on the internet. Set one of them up and just have your clients log a bug there.
Using a template and then getting the clients to copy+paste the old data is one way, but its not exactly the safest method.
If you did want to distribute a new template to your users it would be a good idea to add some import functionality. So VBA handles copying the old data across.
If you (personally) could do the changes to the template manually, then you might also be able to create a workbook+macros to "patch" the source (or a copy of the source) data in-place.
With either approach you'd probably need to add something to the source workbook to keep track of what version they have and make sure they they import from and to the correct version to prevent unhappiness in the future.
Could you show an example of a change? before and after etc
Related
This is a bit of a niche question, as generally it would be preferable to protect the sheet, but I would argue in some cases you simply need to protect the contents of the cell to avoid accidental edits and deletions without limiting editability of the sheet as a whole through Protect Sheet, such as creating new filters.
My Issue:
I have a need to export Revit schedules through a script to an excel spreadsheet for editing, then to import back into Revit. This is because editing elements, especially rooms, can be taxing with the size of our projects and lack of intuitive and quick ways of sorting and replacing contents within Revit schedules. I created a macro that will save the Excel file's fullpath (UNC path for shared network drives), among other things, to a config file to essentially "link" the schedule to that Excel file. If an excel file is not found in the config file, then I create one with through OpenFileDialog() with CheckFileExists = false, and so arises the issue.
If I create a new Excel file and use the Microsoft.Office.Interop.Excel method sheet.Protect("password") when saving the file, the user who export to the newly created file needs to know where to look through the macro in order to unlock the sheet to do some setup that a protected sheet disallows. This would also allow them to alter any protected data, purposefully or otherwise, and compromise the validity of the data. What's worse, if/when I have time to make this into a more developed addin to Revit rather than a macro, the used password would be hidden, disallowing even more trustworthy, advanced users from setting up the sheet. If I allow the user to set the password on creation of the new Excel file, then they can just unlock it whenever they want.
The Need:
The data exported with this script contains an ElementId for the Revit element in addition to what is contained within the Revit schedule, which is needed to tie the Excel data back to a Revit element with 100% accuracy (this is the only unique property of an element that does not change while the element exists). If this is altered in a way that creates a duplicate value in the Excel file, the validity of the import is ruined, and a rollback necessitated (which increases in severity the longer this error goes unnoticed).
Simply hiding the ElmentId column does nothing to prevent user nosiness from unhiding it, and Protect Sheet disallows a small set of needed alterations to the sheet when a new Excel file is created.
So, I need to "protect" against accidental alterations the ElementId column, but still allow for the alteration of that small set of features disallowed by Protect Sheet.
Again, I realize this is pretty niche need and not generally a desired limitation for protecting data. I also realize this does nothing to protect against deletion of the row as with Protect Sheet. That said, my goal is to prevent the alteration of an ElementId value in Excel from being edited into another valid ElementId value, nothing more. As such, deletion of a row would simply mean that the Revit element associated with that specific ElementId would not receive any form of update upon importing the data, as the cell is either null which is skipped or contains an invalid ElementId which can't be associated to an existing element, thus protecting the validity of said element data.
There are two solutions to this. The first was through my own experimentation. The second is a line of thought spawned thanks Solar Mike reminding me of an all too useful feature that I forgot about due to lack of use (generally do not have a need for it): Very Hidden Sheets. The avenue he seemed to be suggesting may not work exactly as he intended as, ideally, this Revit macro and Excel file combo should be usable by anyone in my company, but there is a method to make it work for anyone. Below are the two methods to resolve my issue, and hopefully anyone else in a similar bind that is, for some reason, unable to use Protect Sheet to do this job.
Solution 1: Data Validation
By setting Allow: Custom and Formula: "", I can trigger the Error Alert feature with Style set to "Stop" that will disallow any alterations.
Even better, if I want to disallow the deletion of cell data, unchecking the "Ignore blank" box causes an Error Alert upon hitting the Delete key on the cell as well.
Using this in conjunction with hiding the column obfuscates the process for editing these cells through sheer volume of steps to enable editing, discouraging users from bothering to mess with cell contents.
Pros:
Can utilize Input Message to warn users of the danger of altering cell contents
Can use Error Alert to outright block data entry or deletion of cell contents
Requires additional steps before people can alter values, using effort as a deterrent
Cons:
Does not protect against the following (read further for detailed
descriptions):
Deletion of rows (offset by using this macro on the workbook in
the Visual Basic editor)
Copy and paste another cell(s) over read-only cell(s) (working on a
macro to eliminate this issue)
Alteration of cells through code or macro
Requires macros to mitigate some of the above limitations, which can be
disabled and put data at risk of outlined issues.
Requires additional column (which can and likely should be hidden) in
your data, which becomes obvious to those who look at column letters.
Does not prevent people from turning off data validation, should someone
deem the effort worth it
Deletion of row:
This does not matter as much for me with this solution, as I am reading data from excel row by row, using the ElementId cell to find the Revit element. If an Excel row was deleted, the associated Revit element simply misses get data with that import, and is then re-added into the Excel file from the schdule upon the next export run, as long as the element still exists in Revit. But if row data needs to be maintained to avoid data corruption in your situation, you can use the linked macro to disable it.
Alteration by code:
At least external code; I have not tested this against a VBA macro from within Excel, but I assume the same to be true. I reason this is due to the fact that Data Validation is activated by a user interacting with the cell on an interface level, but when writing to the cell using the Microsoft.Office.Interop.Excel library in C# you are bypassing the interface and interacting directly with the cell data, thus not triggering Data Validation. I am not concerned about security or validation issues arising from this as few in our AEC firm know how to code, and the ones that do have no reason to interact with these files and/or lack the permission to access the folder (seperation of disciplines). While imperfect for most cases, this is the best solution I can come up with for our current needs.
Solution 2: Very Hidden Sheet
This method utilizes two features of Excel:
Very hidden sheet visibility setting
Macros
Specifically, the macro I am referring to is the link from Solution 1's Con section, Prevent Row/Column Removal.
The solution is to have your script write to two different sheets, one for your overall data, and the second for your unique identifiers. The writing of these should be coded in such a way that you would write to a line in each sheet before moving to the next one to ensure the identifier and data are placed on the same row and to reduce errors when editing the code in the future.
When saving the newly generated and format- and filter-less Excel file, set the identifier sheet's visibility to xlSheetVeryHidden, or 2. This setting should be exposed through the Interop.Excel interface as a worksheet property. This way, only advanced users who can use macros can unhide the sheet, and that's if they even know to look for it.
Pros:
Ensures unique identifier is accessible only to those explicitly told of its existence, and even then only to those with the ability or given the tools to access it
By utilizing the Row Deletion Prevention macro, identifier will always be paired with correct data, as long as code writes the data to Excel correctly
Is more secure than Data Validation by way of eliminating copy/paste as a risk
Cons:
Requires file to be saved as .xlsm, or Macro Enabled Workbook, which depending on your company's security settings may send a red flag to those who are unfamiliar with why the file is set this way
If macros are disabled via security settings, validity of data cannot be guaranteed as the row deletion prevention would be disabled
Final Thoughts
While I prefer Solution 2 and the usability it would provide, I can't in good conscience use it. Our firm's OOTB Excel install disables macros by default, and several people consider them non-essential to their tasks in the file and just ignore the warning at the top of the file all together. The risk of data becoming compromised purely because someone doesn't want to enable macros is too great.
I'd also like to add: If you are not in exactly the same situation as me, I do NOT readily recommend either solution. Protect Sheet is the strongest way to protect cell data, and does not disallow the use of existing Sort/Filter features. I am only using these as my go-to solutions due to the experience and/or knowledge level of those in the office who could potentially use my macro (and hopefully future addin), and recognize that neither route is a perfect defense.
If anyone has any other suggestions, I'd appreciate hearing them and I'll definitely update this answer if/when I have a better working version of either solution going.
I'm trying to find solutions for creating a master template in Excel. We have almost 100 Excel workbooks where data in them varies but the formatting and cell and row layout including header names remains the same. When a row is deleted in one, it needs to be deleted in all of them. When a row header is updated, it needs to be updated in all of them. When conditional formatting changes in one, it needs to be updated in all of them. Get the gist?
Solutions I've researched that won't work:
Cell linking - only copies the data and not the format; doesn't account for adding/deleting rows/columns
Format Paint - doesn't work well between different workbooks and still needs to be applied to each workbook individually; doesn't copy conditional formatting; doesn't account for adding/deleting rows/columns
Power Query - formatting is based on the destination file and there's concern that when refreshed it would delete/overwrite all of the data specific to that workbook; doesn't copy conditional formatting
Find/replace - not ideal and doesn't work with exact match (when trying to replace AP it makes no distinction between AP or apply)
MS Access - for business reasons this needs to stay in Excel (i.e. can't use Access or other database programs); this option doesn't address the conditional formatting applied to all of the workbooks
I've seen numerous threads from people looking at how to create a master template in Excel. I get that its not possible (and I have no idea why Microsoft in all its wisdom hasn't created function yet), but what I'm looking for are possible workarounds. Right now the process can take a couple people several days to update all of the workbooks. Any work arounds that can reduce this to a single person in just a few hours would be fantastic.
Posting here in case someone has a VBA suggestion that would encompass everything I need. I'm using Excel 2010 and the workbooks are stored in a document library on SharePoint.
I'm writing a program to read some data from an OOXML Excel Workbook using Apache POI that was provided to me as example input data. There is a strange sheet named D%$&01_DevSheet at the end. It is full of formula cells with weird formulas that reference most of the other sheets in the workbook. Here is an example of one of the cells:
'Horizontal Agreements'!S15+"8I/!%4\"
It is also not visible when the worksheet is opened in Excel.
I've never run across such a sheet before. It looks like some kind of internal Excel structure. Google searches for "D%$&01_DevSheet" and "excel" "DevSheet" have turned up nothing useful.
This sheet is not present in any test workbooks I've created. However, I'm not much of an Excel user and I did not exhaustively try all Excel features.
At this point, I'm going to hard code a rule that excludes sheets ending in _DevSheet from processing. However, since this stuff is turning up in my input, I think I should understand and handle it properly, so I have some basic questions:
What does Excel use sheets like D%$&01_DevSheet for?
What user actions cause them to be created?
Are they named regularly?
What is the most reliable way of detecting sheets like this Apache POI?
Normally Excel does not use such a sheet, so it seems to be added by some specific application or tool that was used to create this Excel workbook. It seems the developer of the application stores formulas and other things in a separate sheet for separation from the user-visible content.
So likely you will need to contact/research whichever application provided this file and get more information about this sheet from there.
You can probably only exclude these sheet by name as you already did.
As far as I understand cells with formulas in Microsoft Office Excel can contain calculated values when serialized and saved in Office Open XML formats (specifically SpreadsheetML). This most likely applies to other types of dependencies and functions of values from other cells (like charts, pivot tables, etc.). I most likely do something wrong, but when processing this XML documents (SpreadsheetML) by external tools, that do not use any .Net components or similar APIs provided by MS, but just directly manipulating XML, I get into a problem that when I modify some content of one of worksheets Excel will still use last generated values in cells containing formulas. So when user opens generated spreadsheet he sees modified data but all the calculated fields are outdated. Now the only thing that I could find (these days) on internet was this:
http://openxmldeveloper.org/discussions/formats/f/14/p/1561/4164.aspx
This is really not a preferable solution especially if it applies to any kind of calculated cells and objects (charts, etc.) as it means partially reimplementing some SpreadsheetML processor when you do not know exactly the structure of all worksheets.
I would hope there would certainly be either an option in Excel or a configuration in one of the SpreadsheetML parts to force recalculations or to mark cells dirty, but I couldn't find one yet.
There is an assumption that scripting would help, but my lack of knowledge of that area didn't brought me to any successful results yet as I'm not sure how to include scripts into SpreadsheetML worksheet. Though I found quite some examples how to trigger recalculation and how to add open event listeners.
The easiest way is to remove the calculated value from the cell (as also noted in the link you provided).
You do not have to know the exact structure of worksheets. Just remove all occurrences of <v>#VALUE!</v> in worksheets/sheet1.xml (so that other functions will not be affected).
press F9 to recalculate all open workbooks
Excel Recalculation
Perhaps your Calculation Mode for the workbook is getting set to manual. Force this mode to Automatic when you open the workbook by setting it to null in the code with the following:
public void SetAutomaticCalculationMode(WorkbookPart workbookPart1)
{
Workbook workbook1 = workbookPart1.Workbook;
CalculationProperties calculationProperties1=workbook1.GetFirstChild<CalculationProperties>();
calculationProperties1.CalculationMode = null;
}
This will correspond to Automatic calculation mode as seen in the Options of Excel 2007 client:
In an Excel sheet, I have roughly 30 rows x 100 columns of data. Each row represents a different "client". For each client, I've create a summary sheet that is emailed to them and that also contains all the information from my main sheet
Is there a way for Excel to create a new sheet based on some template sheet when I add a new row to my main sheet and fill it with the appropriate data?
I will give you my opinion about your need, the way I see it, at least. It is not a "ready to use" solution, however, only some ideas about the way to do that.
From what I know, there is no way to track insertion of a row in Excel. So you would require a VBA function to be activated on a button, for example. Actually, there is, see Lunatik's answer.
This function would loop over all rows in your main sheet, and create a new sheet when necessary (you would need preferably a unique id for each client, it could be a simple index on the main sheet, depending on the line).
You would create at first your template sheet, with a specific name, and eventually hide it (to not have it in the visible tabs). When I say that the function would create, it would in fact copy this template sheet and give it a unique name (the id I mentioned earlier). You can find ways to copy sheets at this link.
A second operation to do, would be to put data from the row in the main sheet, to the template sheet (if I understood correctly your requirement), which is not really complicated to do in VBA.
If you need this to happen automatically on the addition of a row then you would need to use the Worksheet_Change event to capture the completion of a new row.
This would then generate a new workbook from the template, copy across the necessary ranges then save the new file somewhere, much as Gnoupi says
All this is relatively trivial with VBA, but unfortunately if you aren't familiar with VBA then isn't a simple case of "Do X then do Y in Excel" so I think you may struggle, even with sample code posted here.
Even if I created a dummy model that did what you require, functionally at least, then customising it to your particular needs may difficult if you are not used to working with Excel programmatically.
Edit
I've created a very simple demonstration of how this could work: http://drop.io/4clxof3 - note this example doesn't include the event handling for adding a new row, has almost no validation or error handling and makes sweeping assumptions about almost everything(!)
If you feel comfortable using this a basis for developing your own solution then great. If the whole VBA thing is foreign to you then it may be time to call in reinforcements :)
i was wondering if it was possible with no error catching. Simply just have a VBA code that takes each row of the Excel Document - Creates a file for each row and then at the end combines the total files in a folder into one?
I know sounds weird.. but is this possible?