Lets Learn

Opinion Matters

  • Subscribe

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 8 other followers

  • Blog Stats

    • 74,660 hits
  • Ankush

    Error: Twitter did not respond. Please wait a few minutes and refresh this page.

Have you ever thought of inserting an HTML page into Word directly?

Posted by Ankush on July 11, 2017

Have you ever thought of inserting an HTML page into Word directly?

Well, it is very easy.

Simply call ActiveDocument.Range.InsertFile “test.htm”, , , True

Here is the source code for test.htm

==
<html>
This is the image
<img width=625 height=500 src=”image002.jpg”>
</html>
==

But here comes the interesting part. Let’s say you have some images referenced in the HTML page and you insert this HTML page into Word document. Now just delete (rename) the image referenced in the HTML page and open the Word document, you don’t see the images in the document anymore..WHY???

Because they are linked. So to unlink them

====
Sub test()
ActiveDocument.Range.InsertFile ” test.htm “, , , True
ActiveDocument.Fields.Unlink
ActiveDocument.Save
End Sub
====

This code works fine in Word 2003 but doesn’t work in Word 2007 for some reason. To make this to work, you need to call an extra save. Here is an updated code

===============
Sub test()
ActiveDocument.Range.InsertFile “C:\Users\Administrator\Desktop\a.htm”, , , True
ActiveDocument.Save
ActiveDocument.Fields.Unlink
ActiveDocument.Save
End Sub
==============

Hope this helps!!!!

Advertisements

Posted in Uncategorized | Leave a Comment »

Have you ever thought of inserting an HTML page into Word directly?

Posted by Ankush on July 11, 2017

Well, it is very easy.

Simply call ActiveDocument.Range.InsertFile “test.htm”, , , True

Here is the source code for test.htm

==
<html>
This is the image
<img width=625 height=500 src=”image002.jpg”>
</html>
==

But here comes the interesting part. Let’s say you have some images referenced in the HTML page and you insert this HTML page into Word document. Now just delete (rename) the image referenced in the HTML page and open the Word document, you don’t see the images in the document anymore..WHY???

Because they are linked. So to unlink them

====
Sub test()
ActiveDocument.Range.InsertFile ” test.htm “, , , True
ActiveDocument.Fields.Unlink
ActiveDocument.Save
End Sub
====

This code works fine in Word 2003 but doesn’t work in Word 2007 for some reason. To make this to work, you need to call an extra save. Here is an updated code

===============
Sub test()
ActiveDocument.Range.InsertFile “C:\Users\Administrator\Desktop\a.htm”, , , True
ActiveDocument.Save
ActiveDocument.Fields.Unlink
ActiveDocument.Save
End Sub
==============

Hope this helps!!!!

Posted in Uncategorized | Leave a Comment »

Story Points and Bugs in Scrum

Posted by Ankush on July 11, 2017

Classical question isn’t? should we really assign SP (story points) to every bug? If we don’t do it, our velocity will not showcase true value being delivered. Let me outline what I have gathered from my experience:

There could be different category of bugs:

  1. Bugs could be a historical lot.

Let’s say, you are migrating a traditional product to new tech stack which is being implemented in Agile- Scrum. There could be lot of bugs which needs to be implemented/fixed.

Challenge: These types of bugs are not easy to fix. It takes a lot of times to discover what caused it and then implement the solution. I have seen developers spending days to understand the cause of an issue.

My Take: In theory, we should assign SP to these bugs and let PO prioritize the backlog. Team can pick bugs/features based on the priority. Sometimes, it is very difficult to size bugs because one should understand what has caused it. This exercise takes good amount of times. Hence, I have seen Scrum team assign few hours (budget no of hours) and work on them.

 

  1. Bugs could come as part of sprint’s user stories.

You worked on a user story and delivered towards the end of the sprint. QA test it and find bugs in it. How should we handle them? Should we create separate user stories?

Challenge: There are a lot of manual testing and limited UAT and unit testing is performed.

My Take: We should not assign story points to these types of bugs. We already assigned story points to user stories which are consumed in current sprint. Hence, we look for automated approach and try to reduce them. Basically, if we have story certain bugs attached, let’s move that story to new sprint with the less value.

 

  1. Bugs could come after production deployment.

This is a debatable point. A story has already been through testing and PO review. Hence in my opinion, it should be treated as a new feature (The need of the bug is to change the current state of the product to deliver a value). Assigning story points to these items also helps PO to prioritize backlog. Consider, a new feature of X story points vs X story points of few bugs. PO can look those and make an informed decision about the priority.

Let me know your views and thoughts.

Posted in Agile Learnings | Tagged: , , | Leave a Comment »

People Search using Keyword Query in SharePoint 2013

Posted by Ankush on April 24, 2013

Its been a long time since I have blogged. I was busy with some personal activities and now I have free time to start blogging!!

Here is the scenario.  I am developing an application which connects to user profile service a lot and I need to do a lots of filtering/searching based on the custom properties.

One solution could be to use user profile service and then do the work. You will find a lot of sample available online to do it.

One approach (which is efficient) is to use the result sources which has been created for us in SharePoint. Here is the code which I have written to get all the user profiles:

=============
private void button1_Click(object sender, EventArgs e)
        {
            SPSite sp = new SPSite("http://Test:8077/sites/esc/");
// For all employees Use DataTable dt = GetPeople(sp, "*”);         

   DataTable dt = GetPeople(sp, "EmployeeID:" + "101");

            dataGridView1.DataSource = dt;
        }

        private DataTable GetPeople(SPSite spSite, string queryText)
        {

            var keywordQuery = new KeywordQuery(spSite)
            {
                QueryText = queryText,
                KeywordInclusion = KeywordInclusion.AllKeywords,
                SourceId = new Guid("B09A7990-05EA-4AF9-81EF-EDFAB16C4E31")
            };

              keywordQuery.RowLimit = 300;

            keywordQuery.SelectProperties.Add("AccountName");
            keywordQuery.SelectProperties.Add("BloodGroup");
            keywordQuery.SelectProperties.Add("Designation");
            keywordQuery.SelectProperties.Add("SubjectOfExpertise");
            keywordQuery.SelectProperties.Add("PhoneNumber");
            keywordQuery.SelectProperties.Add("MarriageAnniversary");
            keywordQuery.SelectProperties.Add("BoardLineNumber");
            keywordQuery.SelectProperties.Add("EmployeeID");

            SearchExecutor e = new SearchExecutor();
            ResultTableCollection rt = e.ExecuteQuery(keywordQuery);
            var tab = rt.Filter("TableType", KnownTableTypes.RelevantResults);
            var result = tab.FirstOrDefault();
            DataTable DT = result.Table;
            return DT;

        }
========================

The B09A7990-05EA-4AF9-81EF-EDFAB16C4E31 is for People Search. Complete list can be found at:   http://sharepoint.ulitzer.com/node/2501170

If you want to search other sources, just change the guid.

Use the above code and let me know if this is helpful.

Posted in Search, SharePoint 2013 | Tagged: , , , , , | Leave a Comment »

Q 9: Why foreach requires IEnumerable, not IEnumerator?

Posted by Ankush on May 18, 2012

Any Answers??

Posted in Questions | Tagged: , | Leave a Comment »

Projects on Open XML

Posted by Ankush on March 26, 2012

Guys, 

Are you doing any projects on Open XML and SharePoint and need some help.

Then reach out to me..I would love to look into the issues and see if I can be of any help!!!!

 

Posted in Uncategorized | Tagged: , , , , | 1 Comment »

Question on Class Type (Sealed, Public , Virtual)

Posted by Ankush on November 11, 2011

While desgingn the application we normally create classes. Here is a very interesting question:

What’s your opinion on whether to choose “sealed” classes as default, or to leave everything open (public or virtual)?

Share your ideas/thoughts…

Posted in Questions | Tagged: , , , | Leave a Comment »

life Saver of a Developer: Troubleshooting Tools

Posted by Ankush on November 11, 2011

Its been a long time since I have posted anything here. Don’t think I am not concerned about it,it’s just that I am really busy with SharePoint 2010..Learning new things a lot..So here comes a new topic to my mind. Actually I really wanted to write a blog on this a long time back. But as they say, it’s never too late 🙂

So what is this blog all about. Day in day out we deal with different development situations and we always get help with some tools or they help us in RAPID. So what I would like to do: Is to prepare a list of all the tools and put it in one place. In case if you  wish to help the community and want to put a link to a good troubleshooting tool,  please leave the link here with a small note and I will add to the list.

The list is going to grow..so please make sure you add this to Favourites….

Here is how it should be :

Process Explorer
http://technet.microsoft.com/en-us/sysinternals/bb896653

Ever wondered which program has a particular file or directory open? Now you can find out. Process Explorer shows you information about which handles and DLLs processes have opened or loaded

Easy one huh?? But what this tool can also do, to help you know about the Integrity level of a process.  Have a look at this: http://en.wikipedia.org/wiki/Mandatory_Integrity_Control

Named objects, including files, registry keys or even other processes and threads, have an entry in the ACL governing access to them, that defines the minimum integrity level of the process that can use the object. Windows makes sure that a process can write to or delete an object only when its integrity level is equal to or higher than the requested integrity level specified by the object.[2] Additionally, process objects with higher IL are out-of-bounds for even read access.

Consequently, a process cannot interact with another process that has a higher IL. So a process cannot perform functions such as inject a DLL into a higher IL process by using the CreateRemoteThread()API function or send data to a different process by using the WriteProcessMemory() function. However, the higher IL process can execute such functions against the lower IL process.[1] However, they can still communicate by using files, Named pipes, LPC or other shared objects. The shared object must have an integrity level as low as the low IL process and should be shared by both the Low-IL and High-IL process.

Posted in Troubleshooting Basics | Tagged: , , , | Leave a Comment »

Content Types, Features and Events

Posted by Ankush on July 5, 2011

Recently I worked on a case where I had to deploy the XML based site content type through feature and I noticed a strange behavior which makes sense once you know the complete picture. The complete exercise was a very good learning so I thought I will post a blog (or may be a series) on this.

Requirement
=============
Create a site content type based on XML and have an event receiver attached to it.
Use the content type in a list
Modify the Event handler (add some more events)

Actual Results
============

The newly added event will not fire

Expected Result
==============
New events should fire. Even though you update the content type but this doesn’t work. why? Lets just start the learning and the final conclusion process.

Step # 1 –> Create the Site Content Type
============
I started looking out for documentation on this topic and there was not much documentation available> Even if I look into wss.xsd, there was not much help available. So I started building a smaple content type.

So, we need some fields ..lets define fields in an XML file, fields.xml. Create a new XML file in VS and then attach the WSS.XSD and then start typing it.  Please have a look at the sample XML file I have created:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Field Type=”Note”
DisplayName=”Notes”
Required=”FALSE”
MaxLength=”50″
Group=”Sample Columns”
ID=”{165B2AA9-DC9C-4ca5-A004-0CDD19042F20}”
SourceID=”http://schemas.microsoft.com/sharepoint/v3&#8243;
StaticName=”SampleNotes”
Name=”SampleNotes”
RichText=”TRUE”
IsolateStyles=”TRUE”
Sortable=”FALSE”
NumLines=”4″
Hidden=”FALSE”
ReadOnly=”FALSE” />

<Field Type=”URL”
DisplayName=”How To Link”
Group=”Sample Columns”
Required=”FALSE”
Format=”Hyperlink”
ID=”{57632474-85EA-4255-ABE5-A1E6B545766B}”
SourceID=”http://schemas.microsoft.com/sharepoint/v3&#8243;
StaticName=”SampleHowToLink”
Name=”SampleHowToLink”/>

<Field Type=”Choice”
DisplayName=”Status”
Required=”FALSE”
Group=”Task Management Columns”
ID=”{10333110-A154-4321-A04D-6B1D9654DEB8}”
SourceID=”http://schemas.microsoft.com/sharepoint/v3&#8243;
StaticName=”SampleStatus”
Name=”SampleStatus”
Format=”Dropdown”
FillInChoice=”FALSE”>

<CHOICES>
<CHOICE>Active</CHOICE>
<CHOICE>Completed</CHOICE>
</CHOICES>
<Default>Active</Default>
</Field>

</Elements>

 

Once, it is done, lets create the content type which will use these fields (name the file, ContentType.xml):

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentType ID="0x012000ACD1F08FAE0E4478960D38AEFE7769C4"
                   Name="Sample Content"
                   Group="Sample Content Management"
                   Version="0"
                   Sealed="FALSE"
                   Description="Contains Sample Field.">
    <FieldRefs>
      <FieldRef ID="{165B2AA9-DC9C-4ca5-A004-0CDD19042F20}" Name="SampleNotes" Required="TRUE" ShowInNewForm="FALSE"/>
      <FieldRef ID="{57632474-85EA-4255-ABE5-A1E6B545766B}" Name="SampleHowToLink" Required="TRUE" ShowInEditForm="FALSE"/>
      <FieldRef ID="{10333110-A154-4321-A04D-6B1D9654DEB8}" Name="SampleStatus" Required="FALSE" ShowInEditForm="FALSE"/>

</FieldRefs>

</ContentType>
</Elements>

 

You can easily get help on the attributes declared here doing a web search or in SDK so I am not going in detail explaining about them.

Now all we need is a feature.xml which will use the above 2 files.

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/" Id="32F1588E-138B-4abd-ABA2-47A585A61DB3" Scope="Site" Title="Sample Feature">
  <ElementManifests>
    <ElementManifest Location="Fields.xml"/>
    <ElementManifest Location="ContentType.xml"/>
  </ElementManifests>
</Feature>

 

Now we have everything in place, lets try to activate it.

Go to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES and create a folder, SampleContentType and copy Fields.xml, ContentType.xml, feature.xml into this folder.

Open command prompt and browse to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN. (If the environment variable is not set for SharePoint). Run the following command
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>STSADM.EXE -o installfeature -name SampleContentType

Go to Site collection Features and check if the “Sample Feature” is available. If yes, activate it and use it in a list and see how it appears.

Well this is all simple huh..now in the next exercise we will add the event receivers and then try to update them.

Posted in Sp 2007 | Tagged: , , , , | Leave a Comment »

How to Delete a Column in Excel using Open XML SDK

Posted by Ankush on June 13, 2011

Recently there was a question posted on my blog as how we can delete a column in spreadsheet (Excel) using Open XML SDK. Actually, it’s a very tricky requirement because you need to update so much of information i.e. changing the cell index. So it’s really depends how you want to achieve it. You may want to write a COM Addin/VSTO addin to do the job but then you need to deploy the add-in at client side. So, if you are looking for a server side solution, here is the approach. You may want to optimize it according to your need but I will explain in detail what/why I did.

So, let’s start with the concept. Let’s say have created a sample Excel workbook like this:

clip_image001

If you look the XML representation of the data, it will be like this

<x:sheetData xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">

<x:row r="1" spans="1:3" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<x:c r="A1">
<x:v>1</x:v>
</x:c>
<x:c r="B1">
<x:v>2</x:v>
</x:c>
<x:c r="C1">
<x:v>3</x:v>
</x:c>
</x:row>

<x:row r="2" spans="1:3" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<x:c r="A2">
<x:v>1</x:v>
</x:c>
<x:c r="B2">
<x:v>2</x:v>
</x:c>
<x:c r="C2">
<x:v>3</x:v>
</x:c>
</x:row>
</x:sheetData>

So pay attention to how rows and cells are declared. So the declaration is:

Row1
Cell1
Cell2
Cell3

Row2
Cell1
Cell2
Cell3

So for ex: if you delete cell2 from all the rows, you need to update the rowIndex (x:r) in the remaining cells. Let’s say you delete column B , the updated XML should look like this:

<x:row r="1" spans="1:3" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<x:c r="A1">
<x:v>1</x:v>
</x:c>
<x:c r="B1">
<x:v>3</x:v>
</x:c>
</x:row>

<x:row r="2" spans="1:3" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<x:c r="A2">
<x:v>1</x:v>
</x:c>
<x:c r="B2">
<x:v>3</x:v>
</x:c>
</x:row>

And here is the C# code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using DocumentFormat.OpenXml;

using DocumentFormat.OpenXml.Packaging;

using DocumentFormat.OpenXml.Spreadsheet;

using System.Xml.Linq;

 

namespace DeleteSpreadSheetColumn

{

    class Program

    {

        static XDocument columnsXL;

        static void Main(string[] args)

        {

 

            LoadColumnName("");

            string result = DeleteAColumn(@"C:\Users\abhatia\Desktop\Test1.xlsx", "Sheet1", "I");

        }

 

        public static void LoadColumnName(string XMLFile)

        {

            columnsXL = XDocument.Load(@"C:\Users\abhatia\Desktop\ExcelColumn.xml");

 

        }

        // Given a document, a worksheet name, a column name

        // deletes a column from a specified worksheet.

        public static string DeleteAColumn(string docName, string sheetName, string colName)

        {

            // Open the document for editing.

            using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true))

            {

                IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>().Where(s => s.Name == sheetName);

                if (sheets.Count() == 0)

                {

                    // The specified worksheet does not exist.

                    return sheetName + "doesn't exist";

                }

                string relationshipId = sheets.First().Id.Value;

                WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);

 

 

                // Get the Total Rows

                IEnumerable<Row> rows = worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>();

                if (rows.Count() == 0)

                {

                    return "Rows doesn't exist";

 

                }

 

                // Loop through the rows and adjust Cell Index

                foreach (Row row in rows)

                {

                    int index = (int)row.RowIndex.Value;

                    IEnumerable<Cell> cells = row.Elements<Cell>();

 

                    IEnumerable<Cell> cellToDelete = cells.Where(c => string.Compare(c.CellReference.Value, colName + index, true) == 0);

                    if (cellToDelete.Count() > 0)

                        cellToDelete.First().Remove();

 

                    int intColumnToBeDel = (int)(from c in columnsXL.Descendants("col") where c.Attribute("name").Value == colName select c.NodesBeforeSelf().Count()).FirstOrDefault() + 1;

 

 

                    foreach (Cell cell in cells)

                    {

 

                        string col = GetColunName(cell.CellReference.Value);

                        int intColumnPres = (int)(from c in columnsXL.Descendants("col") where c.Attribute("name").Value == col select c.NodesBeforeSelf().Count()).FirstOrDefault() + 1;

 

                        if (intColumnPres > intColumnToBeDel)

                        {

 

                            string ColNamefromXML = ((System.Xml.Linq.XElement)(from c in columnsXL.Descendants("col")

                                                                                where c.Attribute("name").Value + index == cell.CellReference.Value

                                                                                select c.PreviousNode).FirstOrDefault()).FirstAttribute.Value;

                            cell.CellReference.Value = ColNamefromXML + index;

 

                        }

                    }

                }

 

                worksheetPart.Worksheet.Save();

                return "Deleted";

 

            }

        }

 

 

 

        public static bool isNumeric(string val, System.Globalization.NumberStyles NumberStyle)

        {

            Double result;

            return Double.TryParse(val, NumberStyle,

                System.Globalization.CultureInfo.CurrentCulture, out result);

        }

 

        private static string GetColunName(string p)

        {

            Boolean breakLoop = true;

            while (breakLoop)

            {

                if (isNumeric(p.Last().ToString(), System.Globalization.NumberStyles.Integer))

                    p = p.Substring(0, p.Length - 1);

                else

                    breakLoop = false;

            }

            return p;

        }

    }

}

 

Please note that ExcelColumn.xml is just an XML file which contains all the column name. I find it an easy way to get the column name. You can download the complete project and XML file from http://cid-956eb159f7975780.skydrive.live.com/redir.aspx?resid=956EB159F7975780!197

Feel free to optimize it according to your need and let me know if you found any problem with this one!!!

Posted in Open XML SDK, Spreadsheet | Tagged: , , , | 3 Comments »

 
%d bloggers like this: