Popular Posts

Wednesday, December 28, 2011

Excel.Application.Workbooks.Open fails

This is the frustrating error we get:

Microsoft Excel cannot access the file D:\mypath\myexcelfile.xlsx. There are several possible reasons: The file name or path does not exist. The file is being used by another program. The workbook you are trying to save has the same name as a currently open workbook.


This solution is ...


・Windows 2008 Server x64

Please make this folder.

C:\Windows\SysWOW64\config\systemprofile\Desktop

・Windows 2008 Server x86

Please make this folder.

C:\Windows\System32\config\systemprofile\Desktop

...instead of dcomcnfg.exe.

This operation took away office automation problems in my system.

A Desktop folder seems to be necessary in the systemprofile folder to open file by Excel.

It disappears from Windows2008, Windows2003 had the folder, 
and I think it cause this error.

Monday, December 5, 2011

How to move the desktop folder to a different drive

Go to http://www.microsoft.com/ and download the
TweakUI 1.1 powertoy. Make sure you get the separate version as at the time of this
writing the one in the powertoys kit was a different version.

Install it by double clicking on it to expand then find the .inf file and right click on it. 
Select "install" from the menu and it will install. Now open control panel / tweakui and go
to the general tab. In the middle of the screen is the desktop folder and the change location button.
It should be pretty straight forward from there.

Monday, November 28, 2011

Faster and More Effective Long-Term Retention of Data: Taking a Single-System Approach

Organizations around the world require more robust backup and archive-optimised storage sollutions as they look to improve the availability of applications and deal with an explosion in the creation and use of unstructured data. They need storage systems that are optimised for usability in backup and archival environments.

Read this whitepaper to learn about various solutions and how they address many challenges organizations are struggling with.

The Hardest Problems in Data Management. What Are They?

Modern hardware trends and economics, combined with cloud and virtualization technology are radically reshaping today's data management landscape, ushering in a new era where many machine, many core, memory-based computing topologies can be dynamically assembled from existing IT resources and pay-as-you-go clouds.

Arguably one of the hardest problems - and consequently most exciting opportunities - faced by today's solution designers is figuring out how to leverage this on-demand hardware to build an optimal data management platform.

Differences Explained: Private vs. Public vs. Hybrid Cloud Computing

This expert e-guide explains the key differences between private, public and hybrid clouds.

Find out which one best fits your organization's needs by weighing the risks and benefits of each cloud type.

Learn The Five Myths of Cloud Computing

This white paper separates fact from fiction, reality from myth, and, in doing so, will aide senior IT executives as they make decisions around cloud computing.

Some interesting stuff on InfoPath

http://blogs.msdn.com/b/infopath/



SQL Server: Query to find the tables being used in a stored procedure

The query below gets the list of tables that are being referenced in a stored procedure:




SELECT DISTINCT
                 o.id, o.name AS 'Procedure_Name' , oo.name AS 'Table_Name', d.depid
FROM sysdepends d, sysobjects o, sysobjects oo
WHERE   o.id=d.id 
                AND o.name= 'usp_your_sp_here'   -- Stored Procedure Name
                AND oo.id=d.depid 
                
ORDER BY o.name,oo.name

Thursday, November 10, 2011

Windows 7 calculator

There are some very powerful new features hidden in the background. Be sure to explore every option in all Windows applets to ensure you don't miss anything important



Windows 7 calculator

SQL Server Management Studio Keyboard Shortcuts

This link lists down all the SQL Server Management Studio Keyboard Shortcuts

SQL Server Management Studio Keyboard Shortcuts



MS SQL Server : Generate insert statements from values in a table

Create the stored procedure sp_generate_insert_script (You could you any other name you think you could remember easily. I prefer "zinsert") using the code given below.

now, "exec sp_generate_insert_script <table name>" will yeild the insert queries for the table you provide as a parameter to the stored procedure.

To create a shortcut goto Tools->Options->Environment->Keyboard

And place the stored procedure "sp_generate_insert_script" against a key combination you'd like to use.

--------------------------

CREATE  procedure [dbo].[zinsert]     
                 @tablename_mask nvarchar(max) = NULL         
as         
begin         
--------------------------------------------------------------------------------         
-- Stored Procedure:  sp_generate_insert_script         
-- Language:          Microsoft Transact SQL (7.0)         
-- Author:            Inez Boone (inez.boone@xs4al.nl)         
--                    working on the Sybase version of & thanks to:         
--                    Reinoud van Leeuwen (reinoud@xs4all.nl)         
-- Version:           1.4         
-- Date:              December 6th, 2000         
-- Description:       This stored procedure generates an SQL script to fill the         
--                    tables in the database with their current content.         
-- Parameters:        IN: @tablename_mask : mask for tablenames         
-- History:           1.0 October 3rd 1998 Reinoud van Leeuwen         
--                      first version for Sybase         
--                    1.1 October 7th 1998 Reinoud van Leeuwen         
--                      added limited support for text fields; the first 252          
--                      characters are selected.         
--                    1.2 October 13th 1998 Reinoud van Leeuwen         
--                      added support for user-defined datatypes         
--                    1.3 August 4 2000 Inez Boone         
--                      version for Microsoft SQL Server 7.0         
--                      use dynamic SQL, no intermediate script         
--                    1.4 December 12 2000 Inez Boone         
--                      handles quotes in strings, handles identity columns         
--                    1.5 December 21 2000 Inez Boone         
--                      Output sorted alphabetically to assist db compares,         
--                      skips timestamps         
--------------------------------------------------------------------------------         
          
-- NOTE: If, when executing in the Query Analyzer, the result is truncated, you can remedy         
--       this by choosing Query / Current Connection Options, choosing the Advanced tab and         
--       adjusting the value of 'Maximum characters per column'.         
--       Unchecking 'Print headers' will get rid of the line of dashes.         
          
  declare @tablename       nvarchar(max)          
  declare @tablename_max   nvarchar(max)         
  declare @tableid         int         
  declare @columncount     numeric (7,0)         
  declare @columncount_max numeric (7,0)         
  declare @columnname      varchar (1000)         
  declare @columntype      int         
  declare @string          nvarchar(max)         
  declare @leftpart        nvarchar(max)    /* 8000 is the longest string SQLSrv7 can EXECUTE */         
  declare @rightpart       nvarchar(max)    /* without having to resort to concatenation      */         
  declare @hasident        int         
          
  set nocount on          
    
  -- take ALL tables when no mask is given (!)         
  if (@tablename_mask is NULL)         
  begin         
    select @tablename_mask = '%'         
  end         
          
  -- create table columninfo now, because it will be used several times         
          
  create table #columninfo         
  (num      numeric (7,0) identity,         
   name     varchar(1000),         
   usertype smallint)         
          
          
  select name,         
         id         
    into #tablenames         
    from sysobjects         
   where type in ('U' ,'S')         
     and name like @tablename_mask         
          
  -- loop through the table #tablenames         
          
  select @tablename_max  = MAX (name),         
         @tablename      = MIN (name)         
    from #tablenames         
          
  while @tablename <= @tablename_max         
  begin         
    select @tableid   = id         
      from #tablenames         
     where name = @tablename         
      
    if (@@rowcount <> 0)         
    begin         
      -- Find out whether the table contains an identity column    
      select @hasident = max( status & 0x80 )         
        from syscolumns          
       where id = @tableid         
          
      truncate table #columninfo         
           
      insert into #columninfo (name,usertype)         
      select '[' + name + ']', type         
        from syscolumns C         
       where id = @tableid         
         and type <> 37      -- do not include timestamps         
          
      -- Fill @leftpart with the first part of the desired insert-statement, with the fieldnames         
          
      select @leftpart = 'select ''insert into ['+@tablename+']'   
      select @leftpart = @leftpart + '('         
          
      select @columncount     = MIN (num),         
             @columncount_max = MAX (num)         
        from #columninfo         
      while @columncount <= @columncount_max         
      begin         
        select @columnname = name,         
               @columntype = usertype         
          from #columninfo         
         where num = @columncount         
        if (@@rowcount <> 0)         
        begin         
          if (@columncount < @columncount_max)         
          begin         
            select @leftpart = @leftpart + @columnname + ','         
          end         
          else         
          begin         
            select @leftpart = @leftpart + @columnname + ')'         
          end         
        end         
          
        select @columncount = @columncount + 1         
      end         
          
      select @leftpart = @leftpart + ' values('''         
          
      -- Now fill @rightpart with the statement to retrieve the values of the fields, correctly formatted         
          
      select @columncount     = MIN (num),         
             @columncount_max = MAX (num)         
        from #columninfo         
          
      select @rightpart = ''         
          
      while @columncount <= @columncount_max         
      begin         
        select @columnname = name,          
               @columntype = usertype         
          from #columninfo         
         where num = @columncount         
          
        if (@@rowcount <> 0)         
        begin         
          
          if @columntype in (39,47) /* char fields need quotes (except when entering NULL);         
                                    *  use char(39) == ', easier readable than escaping         
                                    */         
          begin         
            select @rightpart = @rightpart + '+'         
            select @rightpart = @rightpart + 'ISNULL(' + replicate( char(39), 4 ) + '+replace(' + @columnname + ',' + replicate( char(39), 4 ) + ',' + replicate( char(39), 6) + ')+' + replicate( char(39), 4 ) + ',''NULL'')'         
          end         
          
          else if @columntype = 35 /* TEXT fields cannot be RTRIM-ed and need quotes     */         
                                   /* convert to VC 1000 to leave space for other fields */         
          begin         
            select @rightpart = @rightpart + '+'         
            select @rightpart = @rightpart + 'ISNULL(' + replicate( char(39), 4 ) + '+replace(convert(varchar(max),' + @columnname + ')' + ',' + replicate( char(39), 4 ) + ',' + replicate( char(39), 6 ) + ')+' + replicate( char(39), 4 ) + ',''NULL'')'  
  
  
   
     
          end         
          
          else if @columntype in (58,61,111) /* datetime fields */         
          begin          
            select @rightpart = @rightpart + '+'         
            select @rightpart = @rightpart + 'ISNULL(' + replicate( char(39), 4 ) + '+convert(varchar(max),' + @columnname + ')+'+ replicate( char(39), 4 ) + ',''NULL'')'         
          end          
    
          else   /* numeric types */         
          begin       
            select @rightpart = @rightpart + '+'         
            select @rightpart = @rightpart + 'ISNULL(convert(nvarchar(max),' + @columnname + '),''NULL'')'          
          end         
          
          
          if ( @columncount < @columncount_max)         
  begin         
      select @rightpart = @rightpart + '+'','''                end         
          
        end         
        select @columncount = @columncount + 1         
      end         
          
    end         
          
    select @rightpart = @rightpart + '+'')''' + ' from [' + @tablename +']'   
          
    -- Order the select-statements by the first column so you have the same order for         
    -- different database (easy for comparisons between databases with different creation orders)         
    select @rightpart = @rightpart + ' order by 1'         
          
    -- For tables which contain an identity column we turn identity_insert on         
    -- so we get exactly the same content         
          
    if @hasident > 0         
       select 'SET IDENTITY_INSERT ' + @tablename + ' ON'         
          
    exec ( @leftpart + @rightpart )         
          
    if @hasident > 0         
       select 'SET IDENTITY_INSERT ' + @tablename + ' OFF'         
          
    select @tablename      = MIN (name)         
      from #tablenames         
     where name            > @tablename       
print @tablename     
  end         
        
      
end     

--------------------------

Shortcut for "Select * from" in SSMS

Create the following stored procedure in your database:

----------------------

CREATE PROC sp_SelectFromTable @tbl VARCHAR (128)
AS
EXEC ('SELECT * FROM ' + @tbl )
GO

-----------------------

Now, goto Tools->Options->Environment->Keyboard
and place the spname "sp_SelectFromTable" against a shortcut key combination you'd like

I prefer Ctrl + 5.

Friday, January 21, 2011

What is the difference between System.Array.CopyTo and System.Array.Clone in .NET?

The Clone() method returns a new array (a shallow copy) object containing all the elements in the original array.

The CopyTo() method copies the elements into another existing array. Both perform a shallow copy.

What is the difference between a DLL and an EXE?

In .NET, an assembly may become a DLL or an EXE. Yet, there is a major underlying difference between the two.

An EXE is an executable file, that may run on its own. Its independant. Where as a DLL is a Dynamic Link Library, that binds to an exe, or another DLL at runtime.

A DLL has an exposed interface, through which members of the assembly may be accessed by those objects that require it.

A DLL runs in tandem with the application space in memory, as the application references it. Whereas an EXE is independant, and runs as an independant process.

How do I make Excel VBA call a dot net dll?

make the DLL COM Visible and register the dll in Windows, otherwise it won't appear in Tools/References. Here are some references

http://msdn.microsoft.com/en-us/library/ms173189(VS.80).aspx
http://support.microsoft.com/kb/817248
http://www.simple-talk.com/dotnet/visual-studio/build-and-deploy-a-.net-com-assembly/
http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/
http://www.csharphelp.com/2006/05/c-classes-as-com-objects/

Introduction

It’s actually very easy to call a .NET library directly from Excel, particularly if you are using Visual Studio 2005. You don’t need Visual Studio Tools for Office. However there doesn’t seem to be an easy guide on the internet anywhere. MSDN help is quite good on the subject, but can be a little confusing. This article is an attempt to redress the situation.

This article was updated 24th August 2007 to cover Excel 2007 and to clarify the issues with intellisense.

A Basic Walk Through

We’ll start by walking through a very basic example. We’ll get Excel to call a .NET method that takes a string as input (for example “ World”) and returns “Hello” concatenated with that input string (so, for example, “Hello World”).

1. Create a C# Windows class library project in Visual Studio 2005 called ‘DotNetLibrary’. It doesn’t matter which folder this is in for the purposes of this example.

2. To call a method in a class in our library from Excel we need the class to have a default public constructor. Obviously the class also needs to contain any methods we want to call. For this walk through just copy and paste the following code into our default class file:

using System; 

using
System.Collections.Generic;
using System.Text;
namespace DotNetLibrary
{
public class DotNetClass
{
public string DotNetMethod(string input)
{
return "Hello " + input;
}
}
}

That’s it: if you look at existing articles on the web, or read the MSDN help, you might think you need to use interfaces, or to decorate your class with attributes and GUIDs. However, for a basic interop scenario you don’t need to do this.

3. Excel is going to communicate with our library using COM. For Excel to use a COM library there need to be appropriate entries in the registry. Visual Studio can generate those entries for us.

To do this bring up the project properties (double-click ‘Properties’ in Solution Explorer). Then:
i) On the ‘Application’ tab click the ‘Assembly Information…’ button. In the resulting dialog check the ‘Make assembly COM-visible’ checkbox. Click ‘OK’.
ii) On the ‘Build’ tab check the ‘Register for COM interop’ checkbox (towards the bottom: you may need to scroll down).

4. Build the library.

5. Now start Excel and open a new blank workbook. Open the VBA code editor:
i) In Excel 2007 this is a little difficult to find. You have to get the Developer tab visible on the Ribbon if it’s not already set up. To do this click the Microsoft Office Button (top left of the screen), then click Excel Options (at the very bottom). Check the ‘Show Developer tab in the Ribbon’ checkbox in the resulting Options dialog. Click OK. This adds ‘Developer’ to the end of the ribbon menu: click this. Then click the ‘Visual Basic’ icon at the left end of the ribbon.
ii) In earlier versions of Office (2003, XP, 2000) just go to Tools/Macro/Visual Basic Editor on the menu bar.

6. We now need to include a reference to our new library. Select ‘References’ on the Visual Basic Editor’s ‘Tools’ menu. If you scroll down in the resulting dialog you should find that ‘DotNetLibrary’ is in the list. Check the checkbox alongside it and click ‘OK’.

7. Now open the code window for Sheet1 (double click Sheet1 in the Project window). Paste the VBA code below into the code window for Sheet1:

Private Sub TestDotNetCall()
Dim testClass As New DotNetClass
MsgBox testClass.DotNetMethod(“World”)
End Sub

8. Click anywhere in the code you’ve just pasted in and hit ‘F5’ to run the code. You should get a ‘Hello World’ message box.

Getting Intellisense Working in Excel

Whilst the VBA code above compiles and executes, you will discover that intellisense is not working in the code editor. This is because by default our library is built with a late binding (run-time binding) interface only. The code editor therefore doesn’t know about the types in the library at design time.

There are good reasons for only using a late-bound interface by default: with COM versioning libraries can become difficult with early-bound interfaces. In particular, if you change the early-bound interface by adding, for example, a method in between two existing methods you are likely to break existing clients as they are binding based on the order of the methods in the interface.

For similar reasons you are heavily encouraged to code your interface separately as a C# interface and then implement it on your class, rather than using the default public interface of the class as here. You then should not change that interface: you would implement a new one if it needed to change.

For more on this see:

http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.classinterfaceattribute(vs.80).aspx
http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.classinterfacetype(VS.80).aspx

However, we can build our library to use early bound interfaces, which means intellisense will be available. To do this we need to add an attribute from the System.Runtime.InteropServices namespace as below:

using System; 

using
System.Collections.Generic;
using System.Text;
using
System.Runtime.InteropServices;
namespace
DotNetLibrary
{
[ClassInterface(ClassInterfaceType.AutoDual)]
public class
{
public DotNetClass()
{
}
public string DotNetMethod(string input)
{
return "Hello " + input;
}
}
}

If you change your code as above it will expose an ‘AutoDual’ interface to COM. This means it is still exposing the late-bound interface as before, but now also exposes an early-bound interface. This means intellisense will work.

To get this working:

1. Save your workbook and close Excel. Excel will lock the DotNetLibrary dll and prevent Visual Studio from rebuilding it unless you close it. Remember you need to save your new code module. If you are using Excel 2007 you will need to save as type Excel Macro-Enabled Workbook (*.xlsm). In earlier versions you can just save as a standard xls.

2. Go back into Visual Studio, change the DotNetClass as shown above, and rebuild the library.

3. Re-open your Excel spreadsheet. Once again if you are using Excel 2007 there is an extra step: you need to explicitly enable macros. A warning bar will appear beneath the ribbon saying the ‘Macros have been disabled’. Click the ‘Options’ button next to this, select ‘Enable this content’, and click OK.

4. Get the VBA code window up again (see item 5 above).

5. Excel can get confused about the interface changes unless you re-reference the library. To do this go to Tools/References. The DotNetLibrary reference should be near the top of the list now. Uncheck it and close the window. Now open the window again, find the library in the list, and re-check it (trust me, you need to do this).

6. Now run the code and it should still work (put a breakpoint in the routine and hit F5).

7. Enter a new line in the routine after the ‘MsgBox’ line, and type ‘testClass.’. When you hit the ‘.’ you should get an intellisense dropdown which shows that DotNetMethod is available. See below.

Intellisense in Excel

Let me re-iterate that this works and is fine for development, but for release code you are better off using the default late binding interfaces unless you understand the full versioning implications. That is, you should remove the ClassInterface attribute from your code when you do a release.

Deployment

In the example here we are using Visual Studio to register our .NET assembly on the workstation so that Excel can find it via COM interop. However, if we try to deploy this application to client machines we’re not going to want to use Visual Studio.

Microsoft have provided a command-line tool, regasm.exe, which can be used to register .NET assemblies for COM interop on client workstations. It can also be used to generate a COM type library (.tlb) separate from the main library (.dll), which is considered good practice in general.

As usual with .NET assemblies you have the choice of strong-naming your assembly and installing it in the GAC, or of not strong-naming it and including it in a local path. If you have strong-named your assembly and installed it in the GAC all you need to do is bring up a Visual Studio 2005 command prompt and run:

regasm DotNetLibrary.dll

If you have not strong-named your assembly you need to tell regasm.exe where it is so that it can find it to register it. To do this you need to run the command below, where c:\ExcelDotNet is the path where DotNetLibrary.dll can be found. This works fine, although it will warn you that you should really strong-name your assembly:

regasm /codebase c:\ExcelDotNet\DotNetLibrary.dll

Note that you can unregister an assembly with the /u option of regasm.

For more detail on this see http://msdn2.microsoft.com/en-us/library/tzat5yw6(vs.80).aspx

Debugging into .NET from Excel

You may want to debug from Excel into your class library. To do this:

1. Using Visual Studio 2005 bring up the Properties window for the class library.

2. Go to the Debug tab and select the ‘Start external program’ option under ‘Start Action’. In the textbox alongside enter the full path including file name to Excel.exe for the version of Excel you are using (usually in Program Files/Microsoft Office/Office).

3. On the same Debug tab under ‘Command line arguments’ enter the full path including file name to your test workbook (the .xls file, or .xlsm if you are using Excel 2007). Once you’re done it should something like below::

Project Properties for Excel

4. Now put a breakpoint in the code (in our example the sensible place is in method DotNetMethod) and hit F5 in the .NET project. The .NET code should compile and Excel should start with your workbook opened. If you now run the VBA code to call the .NET library again, as above, you should find that the code will break at the breakpoint you set in the .NET code.

Possible Problem with these Examples

One problem we have had with these examples is that Excel can get confused about which version of the .NET Framework to load if you have more than one version installed. If this happens you will get an automation error when you try to instantiate .NET objects at runtime from Excel. The .NET types will appear correctly in the Excel object browser.

The workaround for this is to tell Excel explicitly that the version of the .NET Framework that you are using is supported. To do this create a text file called Excel.exe.config and put it in the same directory as Excel.exe itself. The file should contain the text below (with the version number replaced with the .NET Framework version you are using):

xml version="1.0"?> <configuration>   <startup>     <supportedRuntime version="v2.0.50727"/>   startup> configuration>  

References:

Index page from MSDN
http://msdn2.microsoft.com/en-us/library/zsfww439.aspx

More on COM Interop from COM clients into .NET:
http://www.codeproject.com/vb/net/MusaExposingCOM.asp

A COM Class Wizard for C#
http://www.codeproject.com/csharp/cscomtemplate.asp

Guidelines for COM Interoperability from .NET
http://blogs.gotdotnet.com/heaths/archive/2005/03/09/391358.aspx

In Defense of regasm /codebase
http://weblogs.asp.net/savanness/archive/2003/05/29/7749.aspx

Excel/.NET versioning problems
http://krgreenlee.blogspot.com/2006/01/software-running-excel-with-net-11.html


Total Pageviews