How to get the Address of the cells copied from excel via clipboard in Vb.net ?
In Vb6 exe by using
Clipboard.GetText(vbCFLink)
Will able to to get Output as
Excel|[excel path]Sheet1!R48C2:R57C3
How to get the Range of cell copied in vb.net.
In vb.net and vb6 existing methods.
VB6 VB.NET
vbCFBitmap System.Windows.Forms.DataFormats.Bitmap
vbCFDIB System.Windows.Forms.DataFormats.DIB
vbCFEMetafile System.Windows.Forms.DataFormats.EnhancedMetafile
vbCFFiles System.Windows.Forms.DataFormats.FileDrop
vbCFMetafile System.Windows.Forms.DataFormats.MetafilePict
vbCFPalette System.Windows.Forms.DataFormats.Palette
vbCFRTF System.Windows.Forms.DataFormats.Rtf
vbCFText System.Windows.Forms.DataFormats.Text
As per this link For vbCFLink - No equivalent in vb.net
I created a VB6 ocx/dll and used it to get the same result in VB.net appliation but this not feasible for production currently.
Is there any other method to get the Address range of the cells copied from excel via clipboard in Vb.net?
You can still do this with Clipboard.GetData(), you just have to read the stream yourself:
Using reader = New StreamReader(CType(Clipboard.GetData("Link"), Stream))
str = reader.ReadToEnd().Replace(vbNullChar, "|"c)
End Using
(Excuse my VB, it's auto translated from C# so may be a little funny.)
You can examine the current clipboard and all it's formats using this handy utility from Nirsoft, and use GetData() to retreive them.
And with edits suggested by #dr.null, you can create a function to replicate the GetText function:
Function GetTextFromClipboard(type As String) As String
If Not Clipboard.ContainsData(type) Then Return String.Empty
Dim stream = TryCast(Clipboard.GetData(type), Stream)
If stream Is Nothing Then Return String.Empty
Using reader = New StreamReader(stream)
Return reader.ReadToEnd().TrimEnd(ControlChars.NullChar).Replace(ControlChars.NullChar, "|"c)
End Using
End Function
And use it for excel links:
Var str = GetTextFromClipboard("Link")
Related
I'm using PDF Extractor (from here) to get the text from PDF attachments in emails.
It seems to me that the only way I can extract the text is to save the PDF to a file, and then using the code.
Private Function ReadPdfToStringList(tempfilename As String) As List(Of String)
Dim extractedText As String
Using pdfFile As FileStream = File.OpenRead(tempfilename)
Using extractor As Extractor = New Extractor()
extractedText = extractor.ExtractToString(pdfFile)
End Using
End Using
DeleteTempFile()
Return New List(Of String)(extractedText.Split(Chr(13)))
End Function
to extract a list of Strings from the PDF file.
However, I cant seem to extract text from the attachment directly. The 'extractor' doesnt seem to be able to handle any source other than a file on disk.
Is there any possible way of either tricking the 'extractor' into opening a file from memory maybe by creating an in memory file stream?
I've tried using a MemoryStream like this:
Private Function ReadPdfMemStrmToStringList(memstream As MemoryStream) As List(Of String)
Dim extractedText As String
Using extractor As Extractor = New Extractor()
extractedText = extractor.ExtractToString(memstream)
End Using
Return New List(Of String)(extractedText.Split(Chr(13)))
End Function
but because the extractor is assuming the source is a disk file, it returns an error saying that it cant find a temporary file.
To be honest I've spent quite a bit of time trying to understand memory streams and they don't seem to fit the bill.
UPDATE
Here also is the code that I'm using to save the attachment to the MemoryStream.
Private Sub SaveAttachmentToMemStrm(msg As MimeMessage)
Dim memstrm As New MemoryStream
For Each attachment As MimePart In msg.Attachments
If attachment.FileName.Contains("booking") Then
attachment.WriteTo(memstrm)
End If
Next
'this line only adds the memory stream to a List (of MemoryStream)
attachments.Add(memstrm)
End Sub
Many apologies if I've missed something obvious.
First, using VB, how can I check programmatically if Microsoft.Office.Interop.Excel is available in the Excel Object Library ?
Then, if not, is there a way to add it to the reference programmatically ?
The code would be for a VB executable to access values in a spreadsheet, and calling some of the spreadsheet functions as well, if possible.
Try creating the Excel object dynamically. If it succeeds, then Excel is available for use.
Private Function CreateObject(ByVal fullyQualifiedClassName As String) As Object
Dim nspc As String = fullyQualifiedClassName.Substring(0, fullyQualifiedClassName.LastIndexOf("."c))
Dim o As Object = Nothing
Try
For Each ay In Assembly.GetExecutingAssembly().GetReferencedAssemblies()
If (ay.Name = nspc) Then
o = Assembly.Load(ay).CreateInstance(fullyQualifiedClassName)
Exit For
End If
Next
Catch
End Try
Return o
End Function
I have developed a Visual Basic.net application that uses serialization to save an object. I am wanting to open and save this object in two different Visual Basic.net applications.
What is the best way to do this? Do I need to create a class library to do this?
Can I please have some help for this?
EDIT
I am wanting to be able to open and save the object in both applications.
Depending on how complicated your data is, you should be able to simply mark your data's class with a <Serializable> attribute. You can then simply call the Serialize method in one application, save to disk, then read the file into your other application and call Deserialize.
You will need to define the class in both applications, which is easiest to do by sharing a common library.
See the MDSN example for basic serialization.
You can write/read to xml, then you would just have to check the folder where you save them from the other app to see if a new file has been created or updated.
Function to serialize object and write to xml
Public Function MyObjectFileGeneration()
Try
Dim strPath As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
strPath = Replace(strPath, "file:\", "")
Dim myObj = Form1.MyObject
Dim objStreamWriter As New StreamWriter(strPath & "\MyFolder\MyObj.xml", False)
Dim x As New XmlSerializer(s.GetType)
x.Serialize(objStreamWriter, MyObj)
objStreamWriter.Close()
Return True
Catch ex As Exception
'Do something here if failure...
Return False
End Try
End Function
Function to read xml and de-serialize to object
Public Function GetMyObjFromXMLFile() As MyObj
'check if file exists first...
If xmlFileExists() Then
Dim strPath As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
Dim objStreamReader As New StreamReader(Replace(strPath & "\MyFolder\MyObj.xml", "file:\", ""))
Dim MyObj As New MyObject
Dim x As New XmlSerializer(MyObj.GetType)
MyObj = x.Deserialize(objStreamReader)
objStreamReader.Close()
Return MyObj
Else
Return New MyObj
End If
End Function
I wish there was an easy way to do this, but unfortunately, I hit this wall also..
Serializable data can only be reread by the SAME application. (it gives you a lovely error message about this.) I tried using a serialized connection for simplified packet transfers, unsuccessfully..
Depending on how good you are at programming, I have a recommendation on this one..
Serialize your variables to a memorystream, then cut the header section out and shove it to another file stream, then when you reload it, save a variable to a memorystream to get the new header, then attach the remaining data, then read serialization..
haven't tried it yet, but when I get back to it, this is my next method.
I did see an XML method, but recommend using a compression/encryption library to keep your data safe.. did see some simple ways to possibly do that..
Sorry, I don't have code on this round, but when I investigate it, I will append this response..
My application is supposed to parse a text file (relatively easy) and create an excel spreadsheet report.
Should I write a stand alone VB.NET application that saves the excel file, or should I use VSTO? I am unsure if there are any differences in terms of ease of development, usability issues, API functions available, etc.
Are there any other programming languages/interfaces/libraries that will allow me to rapidly develop an involved excel spreadsheet? I am talking about things like functions, graphs, etc.
Thank you
You can do this very easily by taking advantage of excel 2007 format (.xlsx)
Here is what I did, you can modify it pretty easily. Im basically taking advantage that the xlsx file is really just a zip file containing xml files.
I created an empty excel file called Empty.xlsx and added it to my application as a resource. (build action embedded resource)
I'm also using a library for standard zip and unzip since that is how you get at the parts of the excel file.
Here is how i take a datatable and create the excel file.. notice that Excel is not actually needed.
Private Function CreateExcelReport(ByVal FilePath As String, ByVal tbl As DataTable) As FileInfo
'Just loading the excel file from the assembly, you could do it from a file also
Dim _assembly As Assembly = Assembly.GetExecutingAssembly
Dim xlStream As New StreamReader(_assembly.GetManifestResourceStream("YourAssembly.Empty.xlsx"))
'Create a new fileinfo that will hold the outputed excel file with the data.
Dim fiRet As New FileInfo(FilePath)
'Im using Ionic Zip Reduced free library to break the slsx file into its subparts
Using z As ZipFile = ZipFile.Read(xlStream.BaseStream)
'Grab Sheet 1 out of the file parts and read it into a string.
Dim myEntry As ZipEntry = z("xl/worksheets/sheet1.xml")
Dim msSheet1 As New MemoryStream
myEntry.Extract(msSheet1)
msSheet1.Position = 0
Dim sr As New StreamReader(msSheet1)
Dim strXMLData As String = sr.ReadToEnd
'Grab the data in the empty sheet and swap out the data that I want
Dim str2 As XElement = CreateSheetData(tbl)
Dim strReplace As String = strXMLData.Replace("<sheetData/>", str2.ToString)
z.UpdateEntry("xl/worksheets/sheet1.xml", strReplace)
'This just rezips the file with the new data it doesnt save to disk
z.Save(fiRet.FullName)
End Using
'Return a Fileinfo class to be saved to disk or DB or streamed to browser
Return fiRet
End Function
Private Function CreateSheetData(ByVal dt As DataTable) As XElement
Dim sheedata As XElement = <sheetData></sheetData>
'Create Header Rows
Dim HeaderRow As New XElement(<row></row>)
For j = 0 To dt.Columns.Count - 1
Dim c As New XElement(<c t="inlineStr"></c>)
Dim _is As New XElement(<is></is>)
Dim v As New XElement(<t></t>)
v.Add(dt.Columns(j).ColumnName)
_is.Add(v)
c.Add(_is)
HeaderRow.Add(c)
Next
sheedata.Add(HeaderRow)
'Create row for each datarow
For Each dr As DataRow In dt.Rows
Dim newrow As New XElement(<row></row>)
For j = 0 To dt.Columns.Count - 1
Dim c As New XElement(<c t="inlineStr"></c>)
Dim _is As New XElement(<is></is>)
Dim v As New XElement(<t></t>)
v.Add(dr(j).ToString)
_is.Add(v)
c.Add(_is)
newrow.Add(c)
Next
sheedata.Add(newrow)
Next
Return sheedata
End Function
As far as in what form you develop this application, it's really up to you. I would base it on what kind of deployment you would like to use.
If you choose to do it outside of excel, then I would look into EPPlus.
For commercial libraries, you should look at Aspose Cells and SpreadsheetGear.
It's been a while since I've used either, but I recall that the Aspose approach is focused on calling into their libraries from code, and does not require Excel, while SpreadsheetGear is somewhat more template-driven.
I want to get a value from 12 excel sheet. is there any way that i get the values without opening the excel sheet?
I am using vb.net. Please post an example code, if there is a way to read values without opening the excel file.
thanks
You can't read the values without opening the Excel file at all. But you may read the values without having to open Excel.
If the file is saved in the xml format it's going to be easier. If not, the easiest method is to still use Excel but use Office Automation to do it. The hard way is to create an excel file parser - quite hard on the non-open xml excel format (pre Office 2003) - hard but still possible.
However, it is quite impossible to read from an excel spreadsheet without opening the file at all..
Here's a snippet of code you could use to open a spreadsheet from VB.NET, by leveraging Office Automation (it still opens the file, an relies on Excel automation dlls, but doesn't require opening Excel):
DISCLAIMER
The following code is not intended to be used as is, but merely it is a sample to guide the reader to their own solution which should be thoroughly tested.
' The code below requires you to add references to Office Interop assemblies
' into your VB.NET project (if you don't know how to do that search Google)
xlApp = New Excel.ApplicationClass
xlWorkBook = xlApp.Workbooks.Open("<YOUR EXCEL SPREADSHEET FILE HERE")
xlWorkSheet = xlWorkBook.Worksheets("sheet1")
range = xlWorkSheet.UsedRange
For rCnt = 1 To range.Rows.Count
For cCnt = 1 To range.Columns.Count
Obj = CType(range.Cells(rCnt, cCnt), Excel.Range)
' Obj.value now contains the value in the cell..
Next
Next
You can use ADO.NET to read values from an Excel sheet. For more information on the connection string, see http://www.connectionstrings.com/excel-2007
<connectionStrings>
<add name="Default"
connectionString='Microsoft.ACE.OLEDB.12.0;Data Source=c:\your\folder\file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES";'
providerName="System.Data.OleDb" />
</connectionStrings>
You can then use a standard System.Data.OleDb.OleDbConnection to read values from the data source. For example, consider an Excel file that has a sheet named Users, with two columns, UserName and Age.
using System.Data;
using System.Data.Common;
public int UserExists(string userName, int age)
{
var provider = ConfigurationManager.ConnectionStrings["Default"].ProviderName;
var factory = DbProviderFactories.GetFactory(provider);
var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
using (var connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
using (DbCommand command = connection.CreateCommand())
{
DbParameter userNameParameter = factory.CreateParameter();
userNameParameter.ParameterName = "#UserName";
userNameParameter.DbType = DbType.String;
userNameParameter.Direction = ParameterDirection.Input;
userNameParameter.IsNullable = false;
userNameParameter.Value = userName;
DbParameter ageParameter = factory.CreateParameter();
ageParameter.ParameterName = "#Age";
ageParameter.DbType = DbType.Int32;
ageParameter.Direction = ParameterDirection.Input;
ageParameter.IsNullable = false;
ageParameter.Value = age;
command.CommandText = "SELECT COUNT(*) FROM [Users$] WHERE UserName=#UserName AND Age=#Age";
command.Parameters.Add(userNameParameter);
command.Parameters.Add(ageParameter);
connection.Open();
int usersExits = (int) command.ExecuteScalar();
return usersExits == 1;
}
}
}
I don't know of any way to get a value from an Excel spreadsheet without actually opening it but you can access the spreadsheet without having Office installed if that is the problem you are having. Have a look at using the Office primary interop assemblies (see here).
One way is to create an excel application object and set visible = false, then open the excel. I don't know if you are looking for something increase speed or just to avoid having the user see the open and close excel files. I've used this and it works. I'm thinking about using the ADO connections; I've used this with access and they work great, and excel can be used as a database; I just don't know what happens if some of these files don't have the database style array (fields on top, values going down)??