How to optimize this code to create document libraries - c#

This is sharepoint code, but I know c# developers would understand it.
I cant think a way right now to optimize it.
The idea is to create a document library based on the creation of an event, The name of the document library is the startdate in some format + the event title.
The problem is when the user makes many events, the same day, with the same title.
I did it with an IF for only one occurence of the duplication. But there should be another better way to do it.
The idea is to concatenate a number at the end of the doc library /1/2/3 etc.
using (SPSite oSPSite = new SPSite(SiteUrl))
{
using (SPWeb oSPWeb = oSPSite.RootWeb)
{
if (oSPWeb.Lists[DocumentLibraryName] == null)
{
Guid ID = oSPWeb.Lists.Add(DocumentLibraryName, DocumentLibraryName + System.DateTime.Now.ToString(), SPListTemplateType.DocumentLibrary);
SPList oSPList = oSPWeb.Lists[ID];
DocumentLibraryLink = oSPList.DefaultViewUrl;
oSPList.OnQuickLaunch = false;
oSPList.Update();
}
else
{
if (oSPWeb.Lists[DocumentLibraryName + "/1"] == null)
{
Guid ID = oSPWeb.Lists.Add(DocumentLibraryName + "/1", DocumentLibraryName + System.DateTime.Now.ToString(), SPListTemplateType.DocumentLibrary);
SPList oSPList = oSPWeb.Lists[ID];
DocumentLibraryName = DocumentLibraryName + "/1";
DocumentLibraryLink = oSPList.DefaultViewUrl;
oSPList.OnQuickLaunch = false;
oSPList.Update();
}
}
}
}
}

In pseudo-code:
string docLibNameBase ="myLibname";
string docLibNameTemp = docLibNameBase; //we start with the calculated title
int iCounter = 1;
//we check if the currently calculated title is OK
while (listExists(docLibNameTemp, yourWeb)) {
docLibNameTemp = docLibNameBase + "/" + iCounter.toString();
}
//this is where you create the new list using docLibNameTemp as a good title
bool listExists(string docLibName, SPWeb web){
try {
//if there is no list with such name, it will throw an exception
return (web.Lists[docLibname]!=null);
} catch{
return false;
}
}

Related

Revit API SizeTableManager.RemoveSizeTable() not working?

I'm trying to remove all Lookup Tables that start with a specific prefix inside all families.
The method "sizeTableManager.RemoveSizeTable(tableToRemove)" returns true as if it succeeded but when I go edit the families in the project and bring up the Lookup Tables list they are still there.
The transaction seems to be committing with no errors too, which is even more puzzling...
Any ideas as to what I'm doing wrong?
This is my code so far:
string existingPrefix = "ExistingPrefix_";
Document doc = this.ActiveUIDocument.Document;
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> elements = collector.OfClass(typeof(Family)).ToElements();
foreach (var element in elements)
{
using (Transaction t = new Transaction(doc, "flush old lookup tables"))
{
t.Start();
FamilySizeTableManager sizeTableManager = FamilySizeTableManager.GetFamilySizeTableManager(doc, element.Id);
if(sizeTableManager != null)
{
foreach (var tableToRemove in sizeTableManager.GetAllSizeTableNames())
{
if(tableToRemove.StartsWith(existingPrefix))
{
bool result = sizeTableManager.RemoveSizeTable(tableToRemove);
if(result)
{
// TaskDialog.Show("Success", "Removed " + tableToRemove + " from " + element.Name);
var test = "test";
}
else
{
TaskDialog.Show("Warning", "Unable to remove " + tableToRemove + " from " + element.Name);
}
}
}
}
var commitResult = t.Commit();
}
}
Thanks in advance!
Well, turns out that the RemoveSizeTable() method was indeed working, but that I had to regenerate the document for the changes to take effect:
using (Transaction t = new Transaction(doc, "regenerate document"))
{
t.Start();
doc.Regenerate();
t.Commit();
}
Discovered this after noticing that saving the document caused the changes to take effect.

Revit API - Wrong full class name

I'm very new to C# and coding. If possible I'm after some assistance figuring out how to fix this piece of code up to work.
They work individually. I can create a new button on the ribbon and execute the standard hello world. i also have a macro which works where I can remove all my sheets and views successfully but trying to combine the two is causing big difficulties! The code builds OK but I'm getting this error inside revit:
'Failed to initialize the add-in "Delete Views" because the class
"DeleteViews" cannot be found in the add-in assembly.The FullClassName
provides the enrty point for Revit to call add-in application. For
Revit to run the add-in, you must ensure this class implements the
"Autodesk.Revit.UI.ExternalCommand" interface.'
I'm pretty sure my problem is referencing in this 2nd bit of code. i know I'm not calling it up correctly but haven't been able to find any solutions.
Apologies if this is a dumb question but would really appreciate any help to help me learn!
Thanks for any help you can give me
The code:
namespace BGPanel
{
public class CsBGPanel : IExternalApplication
{
public UIDocument ActiveUIDocument { get; private set; }
public Result OnStartup(UIControlledApplication application)
{
RibbonPanel ribbonPanel = application.CreateRibbonPanel("Tools");
string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
PushButtonData buttonData = new PushButtonData("cmdDeleteViews",
"Delete Views", thisAssemblyPath, "BGPanel.DeleteViews");
PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
pushButton.ToolTip = "Delete all sheets, schedules & views except structural plans";
Uri uriImage = new Uri(#"C:\Revit_API\Revit_2015\32px-Broom.png");
BitmapImage largeImage = new BitmapImage(uriImage);
pushButton.LargeImage = largeImage;
return Result.Succeeded;
}
public void DeleteViews()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> collection = collector.OfClass(typeof(View)).ToElements();
using (Transaction t = new Transaction(doc, "Delete Views"))
{
t.Start();
int x = 0;
foreach (Element e in collection)
{
try
{
View view = e as View;
switch (view.ViewType)
{
case ViewType.FloorPlan:
break;
case ViewType.EngineeringPlan:
break;
case ViewType.ThreeD:
break;
default:
doc.Delete(e.Id);
x += 1;
break;
}
}
catch (Exception ex)
{
View view = e as View;
TaskDialog.Show("Error", e.Name + "\n" + "\n" + ex.Message);
TaskDialog.Show("Error", ex.Message);
}
}
t.Commit();
TaskDialog.Show("BG_API DeleteViews", "Views Deleted: " + x.ToString());
}
}
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
}
}
First, instead typing the class name yourself, consider using Reflection like:
typeof(YourClassName).FullName
Second, every command in Revit requires its own class that implements IExternalCommand. I haven't tested, but your code should be something like the following:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Media.Imaging;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace BGPanel
{
public class CsBGPanel : IExternalApplication
{
public Result OnStartup(UIControlledApplication application)
{
RibbonPanel ribbonPanel = application.CreateRibbonPanel("Tools");
string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
PushButtonData buttonData = new PushButtonData("cmdDeleteViews",
"Delete Views", thisAssemblyPath, typeof(DeleteViews).FullName);
PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
pushButton.ToolTip = "Delete all sheets, schedules & views except structural plans";
Uri uriImage = new Uri(#"C:\Revit_API\Revit_2015\32px-Broom.png");
BitmapImage largeImage = new BitmapImage(uriImage);
pushButton.LargeImage = largeImage;
return Result.Succeeded;
}
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
}
public class DeleteViews : IExternalCommand
{
// this will not work...
//public UIDocument ActiveUIDocument { get; private set; }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uidoc = commandData.Application.ActiveUIDocument; //this.ActiveUIDocument;
Document doc = uidoc.Document;
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> collection = collector.OfClass(typeof(View)).ToElements();
using (Transaction t = new Transaction(doc, "Delete Views"))
{
t.Start();
int x = 0;
foreach (Element e in collection)
{
try
{
View view = e as View;
switch (view.ViewType)
{
case ViewType.FloorPlan:
break;
case ViewType.EngineeringPlan:
break;
case ViewType.ThreeD:
break;
default:
doc.Delete(e.Id);
x += 1;
break;
}
}
catch (Exception ex)
{
View view = e as View;
TaskDialog.Show("Error", e.Name + "\n" + "\n" + ex.Message);
TaskDialog.Show("Error", ex.Message);
}
}
t.Commit();
TaskDialog.Show("BG_API DeleteViews", "Views Deleted: " + x.ToString());
}
return Result.Succeeded; // must return here
}
}
}
You should work through the Revit API getting started material before doing anything else at all, especially the DevTV and My First Revit Plugin video tutorials:
http://thebuildingcoder.typepad.com/blog/about-the-author.html#2
Then this question and many other fundamental issues will be answered up front, and you will save yourself and others some effort and head-scratching.
I needed to add a line before the IExternalCommand because of transaction errors when I clicked my button.
[Transaction(TransactionMode.Manual)]
The first answer to this question suggests using the reflection "typeof(YourClassName).FullName" When the sample code is tried it returns a error, understandably as Augusto says he did not test his example. Just adding for anyone down the road... If you use "typeof(DeleteViews).FullName" you would need to cast it into a string variable before the code in his example would work.

Importing submodule using custom importer contains "<module>" in find_module fullname parameter

Currently I'm working on a custom importer for Ironpython, which should add an abstraction layer for writing custom importer. The abstraction layer is an IronPython module, which bases on PEP 302 and the IronPython zipimporter module. The architecture looks like this:
For testing my importer code, I've written a simple test package with modules, which looks like this:
/Math/
__init__.py
/MathImpl/
__init__.py
__Math2__.py
/Math/__init__.py:
print ('Import: /Math/__init__.py')
/Math/MathImpl/__init__.py:
# Sample math package
print ('Begin import /Math/MathImpl/__init__.py')
import Math2
print ('End import /Math/MathImpl/__init__.py: ' + str(Math2.add(1, 2)))
/Math/MathImpl/Math2.py:
# Add two values
def add(x, y):
return x + y
print ('Import Math2.py!')
If i try to import MathImpl like this in a script: import Math.MathImpl
My genericimporter get's called and searchs for some module/package in the find_module method. Which returns an instance of the importer if found, else not:
public object find_module(CodeContext/*!*/ context, string fullname, params object[] args)
{
// Set module
if (fullname.Contains("<module>"))
{
throw new Exception("Why, why does fullname contains <module>?");
}
// Find resolver
foreach (var resolver in Host.Resolver)
{
var res = resolver.GetModuleInformation(fullname);
// If this script could be resolved by some resolver
if (res != ResolvedType.None)
{
this.resolver = resolver;
return this;
}
}
return null;
}
If find_module is called the first time,fullname contains Math, which is ok, because Math should be imported first. The second time find_module is called, Math.MathImpl should be imported, the problem here is, that fullname has now the value <module>.MathImpl, instead of Math.MathImpl.
My idea was, that the module name (__name__) is not set correctly when Math was imported, but i set this in any case when importing the module in load_module:
public object load_module(CodeContext/*!*/ context, string fullname)
{
string code = null;
GenericModuleCodeType moduleType;
bool ispackage = false;
string modpath = null;
PythonModule mod;
PythonDictionary dict = null;
// Go through available import types by search-order
foreach (var order in _search_order)
{
string tempCode = this.resolver.GetScriptSource(fullname + order.Key);
if (tempCode != null)
{
moduleType = order.Value;
code = tempCode;
modpath = fullname + order.Key;
Console.WriteLine(" IMPORT: " + modpath);
if ((order.Value & GenericModuleCodeType.Package) == GenericModuleCodeType.Package)
{
ispackage = true;
}
break;
}
}
// of no code was loaded
if (code == null)
{
return null;
}
var scriptCode = context.ModuleContext.Context.CompileSourceCode
(
new SourceUnit(context.LanguageContext, new SourceStringContentProvider(code), modpath, SourceCodeKind.AutoDetect),
new IronPython.Compiler.PythonCompilerOptions() { },
ErrorSink.Default
);
// initialize module
mod = context.ModuleContext.Context.InitializeModule(modpath, context.ModuleContext, scriptCode, ModuleOptions.None);
dict = mod.Get__dict__();
// Set values before execute script
dict.Add("__name__", fullname);
dict.Add("__loader__", this);
dict.Add("__package__", null);
if (ispackage)
{
// Add path
string subname = GetSubName(fullname);
string fullpath = string.Format(fullname.Replace(".", "/"));
List pkgpath = PythonOps.MakeList(fullpath);
dict.Add("__path__", pkgpath);
}
else
{
StringBuilder packageName = new StringBuilder();
string[] packageParts = fullname.Split(new char[] { '/' });
for (int i = 0; i < packageParts.Length - 1; i++)
{
if (i > 0)
{
packageName.Append(".");
}
packageName.Append(packageParts[i]);
}
dict["__package__"] = packageName.ToString();
}
var scope = context.ModuleContext.GlobalScope;
scriptCode.Run(scope);
return mod;
}
I hope some one has an idea, why this happens. A few line which also may cause the problem are:
var scriptCode = context.ModuleContext.Context.CompileSourceCode
(
new SourceUnit(context.LanguageContext, new SourceStringContentProvider(code), modpath, SourceCodeKind.AutoDetect),
new IronPython.Compiler.PythonCompilerOptions() { },
ErrorSink.Default
);
and
mod = context.ModuleContext.Context.InitializeModule(modpath, context.ModuleContext, scriptCode, ModuleOptions.None);
Because i don't know, whether creating a module this way is completly correct.
The problem can be reproduced downloading this project/branch: https://github.com/simplicbe/Simplic.Dlr/tree/f_res_noid and starting Sample.ImportResolver. An exception in find_module will be raised.
Thank you all!
This problem is solved. Modpath what not allowed to contains /. In general only chars were allowed, which also can be in a file-name.
Maybe this is helpful for someone else...

EWS Search for Fields like Company or Street in Global Address List

I try to write a Webservice that can access to my exchange-server and search for names, companys and cities. At the moment i get the names like this:
ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.UseDefaultCredentials = true;
// Create the ResolveNamesType and set
// the unresolved entry.
ResolveNamesType rnType = new ResolveNamesType();
rnType.ReturnFullContactData = true;
rnType.UnresolvedEntry = "searchname";
// Resolve names.
ResolveNamesResponseType resolveNamesResponse
= esb.ResolveNames(rnType);
ArrayOfResponseMessagesType responses
= resolveNamesResponse.ResponseMessages;
// Check the result.
if (responses.Items.Length > 0 && responses.Items[0].ResponseClass != ResponseClassType.Error)
{
ResolveNamesResponseMessageType responseMessage = responses.Items[0] as
ResolveNamesResponseMessageType;
// Display the resolution information.
ResolutionType[] resolutions = responseMessage.ResolutionSet.Resolution;
foreach (ResolutionType resolution in resolutions)
{
Console.WriteLine(
"Name: " +
resolution.Contact.DisplayName
);
Console.WriteLine(
"EmailAddress: " +
resolution.Mailbox.EmailAddress
);
if (resolution.Contact.PhoneNumbers != null)
{
foreach (
PhoneNumberDictionaryEntryType phone
in resolution.Contact.PhoneNumbers)
{
Console.WriteLine(
phone.Key.ToString() +
" : " +
phone.Value
);
}
}
Console.WriteLine(
"Office location:" +
resolution.Contact.OfficeLocation
);
Console.WriteLine("\n");
}
}
But anybody know how i can serach for Propertys like Company and Street?
EWS only has limited Directory operations if your using OnPrem Exchange then the easiest way to do this is just use LDAP and lookup Active Directory directly. The resolveName operation is meant to be used to resolve a partial number and doesn't work with any other properties. If you have Exchange 2013 then there is the FindPeople operation http://msdn.microsoft.com/en-us/library/office/jj191039(v=exchg.150).aspx which supports using a QueryString which should work if those properties are indexed. eg
EWSProxy.FindPeopleType fpType = new EWSProxy.FindPeopleType();
EWSProxy.IndexedPageViewType indexPageView = new EWSProxy.IndexedPageViewType();
indexPageView.BasePoint = EWSProxy.IndexBasePointType.Beginning;
indexPageView.Offset = 0;
indexPageView.MaxEntriesReturned = 100;
indexPageView.MaxEntriesReturnedSpecified = true;
fpType.IndexedPageItemView = indexPageView;
fpType.ParentFolderId = new EWSProxy.TargetFolderIdType();
EWSProxy.DistinguishedFolderIdType Gal = new EWSProxy.DistinguishedFolderIdType();
Gal.Id = EWSProxy.DistinguishedFolderIdNameType.directory;
fpType.QueryString = "Office";
fpType.ParentFolderId.Item = Gal;
EWSProxy.FindPeopleResponseMessageType fpm = null;
do
{
fpm = esb.FindPeople(fpType);
if (fpm.ResponseClass == EWSProxy.ResponseClassType.Success)
{
foreach (EWSProxy.PersonaType PsCnt in fpm.People)
{
Console.WriteLine(PsCnt.EmailAddress.EmailAddress);
}
indexPageView.Offset += fpm.People.Length;
}
else
{
throw new Exception("Error");
}
} while (fpm.TotalNumberOfPeopleInView > indexPageView.Offset);
Cheers
Glen

The type or namespace name 'ReportingServiceSoapClient' could not be found

I've about given up on this one. I know this is a reporting services web reference however I know it's not either of these below urls.
reportserv/ReportServer/ReportExecution2005.asmx
reportserv/reportserver/ReportService.asmx
reportserv/reportserver/ReportService2005.asmx?wsdl
Does anybody happen to know the URL for this reference? Or does anybody know how to view all the web references on a server?
ReportingServiceSoapClient rs = new ReportingServiceSoapClient();
The type or namespace name 'ReportingServiceSoapClient' could not be
found
I'm telling you ReportingServicesSoapClient and ReportInformation is not there.
I'm using this to view all folders inside of a reporting serices.
ReportingServiceSoapClient rs = new ReportingServiceSoapClient();
rs.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
CatalogItem[] HomeFolders = null;
string reportPath = "/";
rs.ListChildren(reportPath, true, out HomeFolders);
foreach (var homeF in HomeFolders)
{
if (homeF.Type.ToString() == "Folder")
{
Console.WriteLine(homeF.Path + "=> " + homeF.Name + " => is this your home folder? (y/n)");
bool ynLoop = true;
while (ynLoop == true)
{
var readL = Console.ReadLine();
if (readL == "y")
{
ynLoop = false;
TargetHomeFolder = homeF.Path.ToString();
}
else if (readL == "n")
{
ynLoop = false;
}
else
{
Console.WriteLine("You must use y or n");
}
}
if (TargetHomeFolder != "")
{
break;
}
}
}
OMG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I want to get some more frustration out. The difference is simply this. You have to add reportserv/reportserver/ReportService.asmx as a Service reference not a web reference. If you add it as a web reference you will not be able to access it.

Categories