It has been a while since I've coded in Visual Basic, so I forgot much of what I knew when working with MS Excel. I am actually coding within the developer tab of MS Excel 2007.
I have an existing workbook that contains a sheet called "MySheet". In this sheet is a range of cells with text values, and the cells rangefrom A1:A10. I would like to click a button and select the text from any random cell within this range. The text would then be displayed in a message box. Here is what I have so far. This definitely doesn't work though. Any help please? Thanks!
Private Sub myButton_Click()
Dim xl As New Excel.Application
Dim xlsheet As Excel.Worksheet
Dim xlwbook As Excel.Workbook
Dim myCell As Range
Dim rndText As String
Dim rndIndex as Integer
rndIndex = **random number...not sure how**
rndText = ""
xlsheet = xl.Workbook.Sheets("MySheet")
myCell = xlsheet.Cells(rndIndex, 1)
rndText = myCell.Value
MsgBox (rndText)
End Sub
You're definitely on the right track. To get a random number in .NET, here's the way to do it:
Dim rand = new Random()
rndIndex = rand.Next()
'Or you can do this and set a minimum and maximum value for the random number
rndIndex = rand.Next(0, 100)
Related
I'm writing some VBA to check for changes to a spreadsheet when a button is clicked. The spreadsheet makes a copy of itself in the temp directory as determined by the environment variable on Workbook_Open(). This is all working fine, but the problem is with my button_click sub.
Following advice from this question, I'm trying to read the range of interest into an array. The problem is, my array is coming up empty. Is there something stupid that I'm forgetting to do here?
Dim wsOriginalWS As Worksheet
Dim varOriginalSheet As Variant
Dim wbkOrig As Workbook
Dim strRangeToCheck As String
Dim varOriginalSheet As Variant
'... some other non-relevant things
strRangeToCheck = "A5:HC231"
Set wbkOrig = Workbooks.Open(Filename:=FileStr)
Set wsOriginalWS = wbkOrig.Worksheets("Sheet1")
wsOriginalWS.Activate
With wsOriginalWS
Set varOriginalSheet = Range(strRangeToCheck)
End With
'... some other non-relevant things. At this point,
'... wbkOrig is still open, and I can see it with all of its data
'... while debugging.
itemp = getDimension(varOriginalSheet)
I have verified that everything up to Set varOriginalSheet = Range(strRangeToCheck) is working. The spreadsheet in the temp directory opens and is not empty. For some reason varOriginalSheet is empty.
Here's getDimensions:
Function getDimension(var As Variant) As Long
On Error GoTo Err
Dim i As Long
Dim tmp As Long
i = 0
Do While True
i = i + 1
tmp = UBound(var, i)
Loop
Err:
getDimension = i - 1
End Function
EDIT: I wanted to clarify my earlier question. I have existing name formula in my name manager. I would like to set these variables listed below to reference different columns from another document. These variables are referenced in my other spreadsheet.
My question is
1) How do I set the variables to reference another document's column?
2) How can I make it so the Macro allows me to choose which document each time?
Here's my code
Sub UpdateReport()
Dim wbk As Workbook
Set wbk = Workbooks.Open("U:\user\Destination.xls")
Dim x As Variant
Dim FY123 As Range
Dim FY134 As Range
Dim FY145 As Range
Dim FY156 As Range
Dim FY167 As Range
Dim FINCC As Range
Set FINCC = wbk.Worksheets("Worksheet2").Column("D")
Set FY123 = wbk.Worksheets("Worksheet2").Columns("N")
Set FY134 = wbk.Worksheets("Worksheet2").Columns("O")
Set FY145 = wbk.Worksheets("Worksheet2").Columns("P")
Set FY156 = wbk.Worksheets("Worksheet2").Columns("Q")
Set FY167 = wbk.Worksheets("Worksheet2").Columns("R")
End Sub
Thanks,
GS
EDIT: Clarified question
I have a data table in VB.net that I am trying to send to a specific range in an Excel spreadsheet. However, upon running the program I get the error:
An exception of type 'System.Runtime.InteropServices.COMException' occurred in MeasurementFinder.dll but was not handled in user code
Additional information: Exception from HRESULT: 0x800A03EC
The error alerts on the following sub:
Private Sub WriteDataTableToRng(targetWs As Excel.Worksheet, anchor As Excel.Range, tbl As System.Data.DataTable)
'This sub writes the given tbl to the targetWs as a range with its top left cell acting as anchor
Dim wRange As Excel.Range = anchor 'wRange = write range. This range represents the cell being written to over every iteration
For Each colm As DataColumn In tbl.Columns 'This loop writes the column names into the target ws
targetWs.Range(wRange).Value2 = colm.ColumnName '**THIS LINE IS CALLED OUT BY THE ERROR
wRange = wRange.Offset(0, 1)
Next colm
wRange = anchor.Offset(1, 0)
For Each row As DataRow In tbl.Rows
For Each col As DataColumn In tbl.Columns
targetWs.Range(wRange).Value2 = tbl.Rows.Item(tbl.Rows.IndexOf(row)).Item(tbl.Columns.IndexOf(col)) '**THIS LINE IS CALLED OUT BY THE SAME ERROR IF THE PREVIOUS LOOP IS COMMENTED OUT
Next col
Next row
End Sub
The sub that calls the previous one is:
Private Sub ReportOnTube(TubeID As Integer)
'This sub creates an Excel workbook that acts as a report on a tube, given its ID
'The report has a worksheet for each measurement tied to the tube (From the Gauge DB)
'Verify the tube is in the DB
Dim TubeExists As Boolean
TubeExists = VerifyTube(TubeID)
If TubeExists Then
'Create a new excel workbook and name/time stamp it
Dim wb As Excel.Workbook = Me.Application.Workbooks.Add()
wb.SaveAs("C:\Gauge Reports\Tube " & TubeID & System.DateTime.Now.ToString(" HH_mm_ss dd-MM-yyyy"))
'Add a worksheet for each measurement tied to the tube
Dim ws As Excel.Worksheet
ws = wb.Worksheets.Add
Dim aRng As Range
aRng = ws.Range("B2")
TubesConn.Close()
TubesConn.Open()
Dim selectTbl As New SqlCommand("SELECT * FROM [Tubes]", TubesConn)
Dim rdr As SqlDataReader
Dim aTbl As New System.Data.DataTable
rdr = selectTbl.ExecuteReader()
aTbl.Load(rdr)
Call WriteDataTableToRng(ws, aRng, aTbl)
TubesConn.Close()
End If
End Sub
I am using the following imports:
Imports System.Data.Sql
Imports System.Data.SqlClient
Imports System.Data
Imports System.IO
Imports Microsoft.Office.Interop.Excel
What I intend to do is iterate through the given data table and write the values in the table to a range in the spreadsheet whose top left corner is given by the "anchor" range variable. I have no warnings from Visual Stuio's IntelliSense, so I don't really know where to start with this one.
Thanks in advance!
targetWs.Range(wRange).Value2 = colm.ColumnName is redundant/wrong. The excel range object stored in wRange is already a property of the worksheet in which it's contained.
In other words, if you have it print out wRange.Parent.Name you will get the worksheet that the range is in. You can't have a range point to two different worksheets (well maybe through like a range union, I've never tried, but who would do that anyway, you probably can't do it... </streamOfConciousness>)
Instead, just use:
wrange.value = colm.columnName
I think I'm losing my mind - how do you declare a variable as a string and then set it equal to a range in an Excel workbook in VB.NET? In VBA this was easy:
Dim SQL as string
SQL = ActiveWorkbook.Sheets("MySheet").Range("SQL")
If I try do something like this in VB.NET (in Visual Studio 2015), first I can't find Activeworkbook. Second, if I try Excel.Range("SQL"), I get an error saying that 'Range' is an interface type and cannot be used as an expression. Also, it doesn't look like the Range data type exists either. Surely this functionality exists in VB.NET, right?
Thanks for the help!
To work on Excel since VB.NET, first you must add the reference to your Project :
Microsoft.Office.Interop
To Add a Reference :
In Solution Explorer, right-click on the References node and choose Add Reference.
Import the Reference in your code :
Imports Microsoft.Office.Interop
Try to use this code :
Dim AppExcel As New Excel.Application 'Create a new Excel Application
Dim workbook As Excel.Workbook = AppExcel.Workbooks.Add() 'Create a new workbook
Dim sheet As Excel.Worksheet = workbook.Sheets("Sheet1") ' Create variable a Sheet, Sheet1 must be in WorkBook
'Work with range
Dim cellRange1 As Excel.Range = sheet.Range("A1") 'Range with text address
cellRange1.Value = "Text in Cell A1"
Dim cellRange2 As Excel.Range = sheet.Cells(2, 2) 'Range("B2:B2") with index; Cells(N°Row,N°Col)
cellRange2.Value = "Text in Cell B2"
Dim tableRange3 As Excel.Range = sheet.Range("A1:F4") 'Range with text address
Dim tableRange4 As Excel.Range = sheet.Range(sheet.Cells(1, 1), sheet.Cells(4, 6)) 'Range("A1:F4") with index; Cells(N°Row,N°Col)
AppExcel.Visible = True 'To display the workbook
Code without variable sheet
Dim AppExcel as New Excel.Application
Dim workbook As Excel.Workbook = AppExcel.Workbooks.Add()
'Range
Dim cellrange1 as Excel.Range = AppExcel.ActiveWorkbook.Sheets("Feuil1").Range("A1")
You would need to start from your application object. Suppose that's AppExcel:
Dim AppExcel As New Excel.Application
From there, you could do:
Dim cellrange1 as Excel.Range = AppExcel.ActiveWorkbook.Sheets("MySheet").Range("SQL")
Because you've declared cellrange1 as a Range it can't be set to Range("SQL").Value.
Value returns an object which is the value contained in that Range.
That's so wordy. To put it (maybe) more clearly, Range("SQL") returns a Range. Range("SQL").Value returns an object.
If you want to get the value, that would be cellrange1.Value, or perhaps cellrange1.Text. Assuming that the range contains some sort of SQL, I'd go with Text.
An unfortunate aspect of Excel interop programming is that many properties return objects rather than strongly-typed values. For example, the object returned by Range.Text is always going to be a string, but the property still returns an object. That means that Visual Studio intellisense will often not tell you what type a property returns. You'll need to look up properties and functions in the documentation to really know what they return.
I've been trying to write a Macro that changes some formatting in big tables in Word for me. I tried to find this information, but as soon as there are tables, the information is for excel.
So the situation I got is this, I got a table with 6 columns. The first two columns will get selected, the Macro started. Now I'd like it to read the first cell of the selection from the top left, then I do some manipulation/calculations with it, then I'd like to write back the manipulated data, move on to the cell to the right, read the data, manipulate it, write back something and then do so till the end of the Selection.
Can someone help me with a code skeleton? That would be awesome!
Here's a possible skeleton, it loops through columns 1 and 2 of a preexisting table.
Sub TestTable()
Dim wordApp As Word.Application
Dim docDocument As Word.Document
Dim tblTable As Word.Table
Dim c As Word.Cell
Dim sString As String
Dim iColumnNumber As Integer
Set wordApp = CreateObject("Word.Application")
Set docDocument = wordApp.Documents.Open("<location of your document e.g. C:\MyDoc.doc>")
Set tblTable = docDocument.Tables(1)
For iColumnNumber = 1 To 2
For Each c In tblTable.Columns(1).Cells
sString = c.Range.Text
'Do something
Next c
Next iColumnNumber
'wordApp.Visible = True
Set tblTable = Nothing
Set docDocument = Nothing
Set wordApp = Nothing
End Sub