VSTO Msproject: Lock Task - vsto

I'm working on a small addin, when I click on a button, I'd like to set my remainig work and duration to 0 and locked my tasks
So I built something like that, my like function works but it's just to locked my tasks where I have a problem:
foreach (MSProject.Task i_objTask in g_objProject.Tasks)
{
if (i_objTask.WBS.like(WbsIndex+"%"))
{
i_objTask.RemainingWork = 0;
i_objTask.RemainingDuration = 0;
**Here I'd like to add something like : i_objtTask.Locked=true but this proprety doesn't exist****
}
}
Any idea of how could I do that?

Record Macro (under the Developer ribbon) is handy for this stuff. Using it gets you:
SetTaskField field:="Locked", value:="Yes"
Unfortunately, you have to select & iterate through tasks on the Task Sheet to manipulate tasks' fields in this way. I haven't seen a Task object property that you can set directly to manipulate the locked state.

Related

ImageJ batch processing - opening a series of images containing a specific name and doing stuff on them

I have 25K tif files (please don't ask why) that I want to organize into stacks on image J. Basically for each region of interest (ROI), there are 50 images which breaks down into 25 z-planes for two channels. I want everything in a single stack. And I'd like to batch process the whole folder without opening 50 images 500 times at a time. I've attached a picture of what the file names look like:
Folder organization
r01c01f01p01-ch1.tif - the first 10 characters are unique ID to each ROI, then plane number (p01) then channel - ch1 or ch2, then file extension
Here's what I have so far (which I cobbled together based on other macros so this may not make sense...).This is using the ImageJ macros language.
//Processing loop to process each file in the folder.
for (i=0; i<list.length; i++) {
showProgress(i+1, list.length);
if (endsWith(list[i], ".tif")) { // skip the subfolder (I create a subfolder earlier in the macros)
print("-- Processing file: " + list[i] + " --");
open(dir+list[i]);
imageTitle= getTitle();
newTitle = substring(imageTitle, 0, lengthOf(imageTitle)-10); // r01c01f01p, cutting off plane number and then the rest to just get the ROI ID
//This is where I'm stuck:
// find all files containing newTitle and open them (which would be 50 at a time), then run the following macros on them
run("Images to Stack", "name=Ch1 title=[] use");
run("Duplicate...", "title=Ch2 duplicate");
selectWindow("Ch1");
run("Slice Remover", "first=1 last=50 increment=2");
selectWindow("Ch2");
run("Slice Remover", "first=2 last=50 increment=2");
run("Merge Channels...", "c1=Ch1 c2=Ch2 create");
saveAs("tiff", dirNew + newTitle + "_Stack.tif");
//Close(All)?
}
}
print("-- Done --");
showStatus("Finished.");
setBatchMode(false); // Exit batch mode
run("Collect Garbage");
Thank you!
You could do something like:
for (plane=1; plane<51; plane++) {
open(newTitle+plane+"-ch1.tif");
open(newTitle+place+"-ch2.tif");
}
Which would take care of the opening. I would be inclined to have a loop prior to this which would collate the number of unique "newTitle"'s, as your current setup would end up doing something like opening the first item, assembling the combined TIF, and then repeat the process 25K times if I understand it correctly.
Given that you know the number of unique "r01c01f01p" values, in principle you could do a set of stacked loops akin to:
newTitleArray = newArray();
for (r=1; r<50; r++) {
titleBit = "r0" + toString(r);
for (c=1; c<501; c++) {
titleBit = titleBit + "f0"...
Alternatively, you could set up a loop where you check for unique "r01c01f01p" values and add them to an array. In any case, you'd replace the for "list" loop with the for "newTitleArray" loop, and then continue onto the opener I listed above, instead of your existing one.
If I am understanding correctly, it seems like you might do well to stack by channel first, then merge the two. I am not 100% sure, but I think you could potentially use a macro I have already created to do that. It was originally meant to batch process terabytes of 5D data, so it should be very comfortable handling your volume of images. It is not exactly what you are looking for, but should be super easy to modify (I went a little overboard with the commenting in the code), and I think the only thing it does that you might rather it not is produce max projects from the inputs. I'll throw a link here and look for your reply. If it's of interest, let me know and we can work to make it suit your needs together :-) Otherwise, if you could provide a little more detail about where you're getting stuck and/or where I may have misunderstood, I will do my very best to help!
https://github.com/evanjkiely/FIJIMacros

How can I avoid duplicating logic in Control Flow

I have a package which looks as follows:
Notice the two areas which I have marked with a red rectangle: they are identical in every way. Can I make changes to the package so I can avoid this duplication? It seems to me I cannot move them to a Data Flow Task since loops and File System Task do not exists there.
You can create a sub package for the Loop logic as #Bill mentioned, and the way to 'pass the resultset of a query on to another package' is as below (use SSIS 2012 as the example, I did the similar work SSIS 2005, so you only need to change the c# code to vb.net)
In your parent package, create a variable to hold the name of the resultSet variable in the parent package:
In your sub package, create a string variable parentResultSetName:
In your sub package, add a package configuration to mapping the parentResultSetName to the parent package variable resultSetVariableName:
Now, we can read the resultSet variable by the name in the script task of sub package:
public void Main()
{
// TODO: Add your code here
var dsName = Dts.Variables["parentResultSetName"].Value.ToString();
Variables variables = null;
DataSet resultSet = null;
Dts.VariableDispenser.LockForRead(dsName);
Dts.VariableDispenser.GetVariables(ref variables);
try
{
resultSet = variables[dsName].Value as DataSet;
if (resultSet != null)
{
MessageBox.Show("Sub package get: " + resultSet.Tables[0].Rows[0][0].ToString());
}
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception e)
{
Dts.Events.FireError(-1, "", e.Message, "", 0);
}
}
Here is the result:
Just place both your queries from "select batch logins" tasks to recordset and make another foreach loop over that recordset, executing those two queries from a variable.
I can see that in your second foreach loop there are some additional tasks, so you'll have incorporate them to "Select all batch logins" task somehow, or make constraints that'd match in both loops.
An alternative approach is to add an 'action' column to your 'batches' table. (or add an outrigger table). Work out beforehand what you want to do to the records. Then just delete the records and files once.
It looks like you are doing RBAR operations here.
So for example you run a couple of UPDATE statements against your tables that leave the tables in a state where each record is flagged for deletion or not.
Then after that you go through the loop and delete based off what is in the table.
It would make your package a lot simpler. and you can incorporate some 'commit' logic that makes sure a record and file are always deleted at the same time.

Semantic Zoom Catastrophic failure on empty group

I am using the SemanticZoom control with a grid view and collection view source. All is working fine until I attempt to select ('jump to') an empty group - this causes an unhandled Catastrophic failure.
http://social.msdn.microsoft.com/Forums/nb-NO/winappswithcsharp/thread/6535656e-3293-4e0d-93b5-453864b95601
Does anybody know if there is a way to fix this - I want to 'allow' an empty group if I can.
Thanks
Okay, so I ran into this issue and fixed it. I know this is quite an old thread, but I'll answer it in case someone else runs into this. Here's how I did it.
The issue seems to be that the group set as the DestinationItem needs to have items in it. In the case that this group is empty, this poses a problem. The problem does not occur when the group is in between other filled groups, because it has a length of 0 and therefore is untargetable. When it is at the end (or possibly the beginning, haven't tried that), this poses an issue because the GridView/ListView targets the last one in the list when the mouse is past the end of the view.
So, how to solve it:
You need to add an event handler for OnViewChangeStarted. In this handler, you will have access to the SemanticZoomViewChangedEventArgs.
The first thing you need to do is find out if the Group being targetted is empty. I am using a custom Group class here, but have cast it to IEnumerable, just because I only need to know how many items are in it. Linq allows me to find the count of the IEnumerable.
using System.Linq;
private void Zoom_OnViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e)
{
var group = e.DestinationItem.Item as IEnumerable;
if (group != null && group.Count() == 0)
{
e.DestinationItem.Item = MyViewModel.Groups.Last(itemGroup => itemGroup.Count() > 0);
}
}
As you'll note, the next step is to set the DestinationItem.Item to the Last group that has items in it. You may also want to handle the First group that has items in it, but that's quite easy to do as well. In place of MyViewModel, insert your ViewModel. In place of Groups, insert your collection property.
I hope this helps and happy coding!

Excel "Refresh All" with OpenXML

I have an excel 2007 file (OpenXML format) with a connection to an xml file. This connection generates an excel table and pivot charts.
I am trying to find a way with OpenXML SDK v2 to do the same as the "Refresh All" button in Excel. So that I could automatically update my file as soon as a new xml file is provided.
Thank you.
Well there is quite good workaround for this.
Using OpenXML you can turn on "refresh data when opening the file" option in pivot table (right click on pivot table->PivotTable Options->Data tab).
This result in auto refresh pivot table when user first opens spreadsheet.
The code:
using (var document = SpreadsheetDocument.Open(newFilePath, true))
{
var uriPartDictionary = BuildUriPartDictionary(document);
PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart1 = (PivotTableCacheDefinitionPart)uriPartDictionary["/xl/pivotCache/pivotCacheDefinition1.xml"];
PivotCacheDefinition pivotCacheDefinition1 = pivotTableCacheDefinitionPart1.PivotCacheDefinition;
pivotCacheDefinition1.RefreshOnLoad = true;
}
you need to determine "path" to yours pivotCacheDefinition - use OpenXML SDK 2.0 Productivity Tool to look for it.
BuildUriPartDictionary is a standard method generated by OpenXML SDK 2.0 Productivity Tool
protected Dictionary<String, OpenXmlPart> BuildUriPartDictionary(SpreadsheetDocument document)
{
var uriPartDictionary = new Dictionary<String, OpenXmlPart>();
var queue = new Queue<OpenXmlPartContainer>();
queue.Enqueue(document);
while (queue.Count > 0)
{
foreach (var part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
{
uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
queue.Enqueue(part.OpenXmlPart);
}
}
return uriPartDictionary;
}
Another solution is to convert your spreadsheet to macroenabled, embed there a VBA script that will refresh all pivot tables.
This can happen on button click or again when user opens spreadsheet.
Here you can find VBA code to refresh pivot tables:
http://www.ozgrid.com/VBA/pivot-table-refresh.htm
You can't do this with Open XML. Open XML allows you to work with the data stored in the file and change the data and formulas and definitions and such. It doesn't actually do any calculations.
Excel automation technically would work, but it's absolutely not recommended for a server environment and is best avoided on the desktop if at all possible.
I think the only way you can do this is following this type of method..
Save Open XML workbook back to a xlsx file.
Load the workbook using the Excel object model.
Call either
ThisWorkbook.PivotCaches(yourIndex).Refresh();
or
ThisWorkbook.RefreshAll();
although I was pretty sure RefreshAll would also work.
Use the object model to Save the workbook and close it.
Reopen for use with xml namespaces.
The solution provided by Bartosz Strutyński will only work if the workbook does contain pivot tables and they share the same cache. If the workbook does not contain pivot tables, the code will throw a NullPointerException. If the workbook contains pivot tables that use different caches (which is the case when data sources are different), only one group of pivot tables that use the same cache will be refreshed. Below is the code based on Bartosz Strutyński's code, free of the aforementioned limitation, and not relying on knowing the "path" of PivotCacheDefinition object. The code also inlines BuildUriPartDictionary, which allows avoiding enumeration of uriPartDictionary in case it’s not used somewhere else, and uses explicit types, to ease searching documentation for the used classes.
Dictionary<String, OpenXmlPart> uriPartDictionary = new Dictionary<String, OpenXmlPart>();
Queue<OpenXmlPartContainer> queue = new Queue<OpenXmlPartContainer>();
queue.Enqueue(document);
while (queue.Count > 0)
{
foreach (IdPartPair part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
{
uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
queue.Enqueue(part.OpenXmlPart);
PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart;
if ((pivotTableCacheDefinitionPart = part.OpenXmlPart as PivotTableCacheDefinitionPart) != null)
{
pivotTableCacheDefinitionPart.PivotCacheDefinition.RefreshOnLoad = true;
}
}
}

How do I use Linq-to-sql to iterate db records?

I asked on SO a few days ago what was the simplest quickest way to build a wrapper around a recently completed database. I took the advice and used sqlmetal to build linq classes around my database design.
Now I am having two problems. One, I don't know LINQ. And, two, I have been shocked to realize how hard it is to learn. I have a book on LINQ (Linq In Action by Manning) and it has helped some but at the end of the day it is going to take me a couple of weeks to get traction and I need to make some progress on my project today.
So, I am looking for some help getting started.
Click HERE To see my simple database schema.
Click HERE to see the vb class that was generated for the schema.
My needs are simple. I have a console app. The main table is the SupplyModel table. Most of the other tables are child tables of the SupplyModel table.
I want to iterate through each of Supply Model records. I want to grab the data for a supply model and then DoStuff with the data. And I also need to iterate through the child records, for each supply model, for example the NumberedInventories and DoStuff with that as well.
I need help doing this in VB rather than C# if possible. I am not looking for the whole solution...if you can supply a couple of code-snippets to get me on my way that would be great.
Thanks for your help.
EDIT
For the record I have already written the following code...
Dim _dataContext As DataContext = New DataContext(ConnectionStrings("SupplyModelDB").ConnectionString)
Dim SMs As Table(Of Data.SupplyModels) = _dataContext.GetTable(Of Data.SupplyModels)()
Dim query = From sm In SMs Where sm.SupplyModelID = 1 Select sm
This code is working...I have a query object and I can use ObjectDumper to enumerate and dump the data...but I still can't figure it out...because ObjectDumper uses reflection and other language constructs I don't get. It DOES enumerate both the parent and child data just like I want (when level=2).
PLEASE HELP...I'M stuck. Help!
Seth
in C# it would be:
var result = from s in _dataContent.SupplyModels where s.SupplyModelID==1 select s;
foreach(SupplyModel item in result)
{
// do stuff
foreach(SupplyModelChild child in item.SupplyModelChilds)
{
//do more stuff on the child
}
}
and a VB.NET version (from the Telerik code converter)
Dim result As var = From s In _dataContent.SupplyModels _
Where s.SupplyModelID = 1 _
Select s
For Each item As SupplyModel In result
' do stuff
'do more stuff on the child
For Each child As SupplyModelChild In item.SupplyModelChilds
Next
Next