Running Macro on a WokSheet of Excel - vba

I am able to create a excel from Python win32com ,so i know all the details of excel viz. Total number or rows , columns , Worksheet Names and location where it is saved. Now i want to run some application which can run a macro on a worksheet of created excel .
Example of macro :
Sub Macro2()
'
' Macro2 Macro
'
'
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlPie
ActiveChart.SetSourceData Source:=Range("C2:C6")
End Sub
Please tell which application can do this .

Well as you are probably aware, a little bit of work might be involved, but xlwings should be right up your street. For example from within VBA we can import functions by calling Python. From the docs:
Sub MyMacro()
RunPython ("import mymodule; mymodule.rand_numbers()")
End Sub
#which will run the following or any required, saved function.
import numpy as np
from xlwings import Workbook, Range
def rand_numbers():
wb = Workbook.caller() # Creates a reference to the calling Excel file
n = Range('Sheet1', 'B1').value # Write desired dimensions into Cell B1
rand_num = np.random.randn(n, n)
Range('Sheet1', 'C3').value = rand_num
Enjoy, http://xlwings.org/

Related

Running excel macros only on one sheet

Hi Iam new to writing VBA code and need assistance. My VBA code and Macro works fine as long as I am on the active sheet.
My Problem:
My VBA code and macro, stops running automatically, when i change from the active sheet to another within the same workbook and
My VBA code and macro, stops running automatically, when i open a new excel workbook
Solution required:
Run the VBA code and macro only on desired worksheet and prevent it from running on other worksheets and workbooks.
Background:
I have an excel file, named "Net Weight" with two sheets. sheet 1 is named : "weight", sheet 2: is named "base data".
sheet 1 is used as a user input form.
In sheet 1- cell B1 : user will type in a product code , in cell E1: a look up formula will place the description of the product code using the data from sheet 2
I have setup a VBA code and macro that does the following:
As soon as a user inputs a product code into cell B1, in sheet 1, sheet 1 is saved as PDF file into a predefined folder location data from cell B1 and E1
A macro saves and overwrties the PDF file every 10 seconds.
This process is repeated every time a new product code is entered
There are no buttons on sheet 1, everything is done automatically.
Here is my current code:
Sheet 1: set as Worksheet
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$1" Then
Call Macro1
End If
End Sub
Module 1 macro : set as general
Sub Macro1()
Application.DisplayAlerts = False
If ThisWorkbook.Name = "Nett Weight.xlsm" And ActiveSheet.Name = "Weight" Then
Sheets("Weight").ExportAsFixedFormat Type:=xlTypePDF, _
Filename:="C:\Nett weight\" & Range("B1 ").Text & Range(" E1").Text
Application.OnTime Now + TimeValue("00:00:10"), "Macro1"
Else
Exit Sub
End If
End Sub
First, you need to create a public variable to hold your timer, otherwise you'll never be able to cancel it so it will continue trying to fire even when your workbook is closed. You should also create a public variable to store when the timer is running, so you can check before creating a new timer.
At the top of a code module put:
Public nextTime As Date
Then in your Workbook_BeforeClose() event method (within ThisWorkbook), disable the existing timer so it doesn't keep trying to fire after the workbook is closed.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next ' Continue with next line of code if we encounter an error
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=False
On Error GoTo 0 ' Resume error-trapping
End Sub
In Macro1() you should explicitly and directly reference your workbook components - ThisWorkbook always refers to the workbook the code is running from, so you don't need your If statement. Then you set the nextTime and activate the timer using that variable if it is not already running.
Sub Macro1()
Dim sht As Worksheet ' Creates a variable to hold your Weight worksheet
Set sht = ThisWorkbook.Sheets("Weight") ' Sets the reference
Application.DisplayAlerts = False
sht.ExportAsFixedFormat Type:=xlTypePDF, Filename:="C:\Nett weight\" & sht.Range("B1").Text & sht.Range("E1").Text ' Remember to preceed Range with sht. to explicitly reference the range of your Weight worksheet
On Error Resume Next ' Continue with next line of code if we encounter an error
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=False
On Error GoTo 0 ' Resume error-trapping
nextTime = Now + TimeSerial(0, 0, 10) ' Adds 10 seconds to Now
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=True
timerIsRunning = True
Application.DisplayAlerts = True ' Remember to enable alerts at the end of code
End Sub
Your Worksheet_Change() event method can stay as is. Now if there is a change in B1 it will call Macro1(). Macro1() will save the Weight worksheet as a PDF regardless of whether the workbook or worksheet is active, and create a new timer to re-run Macro1() every 10 seconds after deactivating an existing timer. When you're finished with the workbook, you close it and the existing timer is also deactivated.
EDIT:
Fortunately (as it fixes a spreadsheet of my own) I have figured out why the solution I originally provided wasn't working. Placing the Public variables under ThisWorkbook meant they no longer held their values after code execution. The remedy was to place them in a module instead. Once that was sorted out, I also realised that when the timer fires to call Macro1() it will throw an error when trying to unschedule the existing timer (as none exists unless Macro1() was called ad hoc by the Worksheet_Change() event).
Long story short: Public variables have been moved to a code module, and the timerIsRunning flag has been removed entirely and errors when attempting to unschedule the timer are simply ignored in the event that no timer exists.

shape name changes all the time i can not find it

I have this Problem for deleting a shape in Excel with vba. Excel gives all the time different Name to These shapes, thatswhy i get error on this line:Here Activesheet is my open sheet and straight connectgor 1 is the Name of the shape, it is set as "Straight Connector 1" but when i reuse the macro it can not be found.
ActiveSheet.Shapes.Range(Array("Straight Connector 1")).Select
Selection.Delete
It can not find the element if i use the macro again. What should i do for this ?
use the activtsheet.shapes collection
Sub connector_delete()
Dim s As Shape
For Each s In ActiveSheet.Shapes
If s.AutoShapeType = msoShapeMixed And s.Name Like "*Connector*" Then
s.Delete
End If
Next s
End Sub

How to make an Excel chart with vba that have two category axis

I have data in excel sheet like this
Country Product Price
America A 43
China B 13
Germany C 21
Turkey D 12
In excel i select this data and make a chart out of it that seems like this
But the problem is when i select the same data with vba and draw the chart from vba then it results into
Now i want the vba chart to display to category axis as same as we select data from excel and draw the chart.
In short i want the vba chart to automatically adjust according to the data.
Here is the code.
Sub CreateChart()
Range("a1").Select
Selection.CurrentRegion.Select
myrange = Selection.Address
mysheetname = ActiveSheet.Name
Worksheets(1).Activate
'ActiveWindow.DisplayGridlines = False
' Add a chart to the active sheet.
ActiveSheet.ChartObjects.Add(125.25, 60, 301.5, 155.25).Select
Application.CutCopyMode = False
ActiveChart.ChartWizard _
Source:=Sheets(mysheetname).Range(myrange), _
Gallery:=xlColumnStacked, Format:=10, PlotBy:=xlRows, _
CategoryLabels:=1, SeriesLabels:=1, HasLegend:=1, _
Title:=charttitle, CategoryTitle:=chartcategory, _
ValueTitle:=chartvalue, ExtraTitle:=""
End Sub
It's very simple in Excel. Record a macro while inserting the chart and selecting the data for the chart. The recorder records the VBA steps and gives you the neat code which can do the same whenever you execute. For instance, the recorder gave me this 2 lines of code:
Sub Macro1()
ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select
ActiveChart.SetSourceData Source:=Range("A2:C5"), PlotBy:=xlColumns
End Sub
Pretty simple, isn't it?
If you just wana to update data in already existing chart, better solution can be to update them. Basicaly create chart which you desire and assign some name to it. (for example myLovelyChart)
Sub updateChartSO()
Dim chartSheet As Worksheet
Set chartSheet = Sheets("testSheet")
Dim chtSerie As Series
With chartSheet
For Each chtSerie In .ChartObjects("myLovelyChart").SeriesCollection
'specify your values, can be specified by array or even from sheet'
chtSerie.Values = ""
chtSerie.XValues = ""
Next
End With
End Sub
Or if you really wana to create new chart, take a closer look at chartType property (https://msdn.microsoft.com/en-us/library/office/ff820803.aspx) and its enumeration (https://msdn.microsoft.com/en-us/library/office/ff838409.aspx)
In VBA, it auto define the format based on data range.
However, You can using below code to control it
Chart(1).PlotBy = xlRows
OR
Chart(1).PlotBy = xlColumns

Excel VBA Can't access sheet on external workbook

I have created a custom function in Excel using VBA. I'm trying to get data from a different workbook using the Workbooks.Open(path) command. Here's my code:
Option Explicit
Function TestFunction() As String
mySub
TestFunction = "Success."
End Function
Sub mySub()
Dim path As String
Dim wk As Workbook
path = "C:\Users\jg\Desktop\machine_data.xlsm"
Set wk = Workbooks.Open(path)
Dim ws As Worksheet
Set ws = wk.Sheets(1)
Debug.Print ws.Range("A2")
End Sub
Sub Test()
Debug.Print (TestFunction())
End Sub
Now my problem is the following:
When I run the Sub Test() within the VBA environment from Excel everything works as planned. machine_data.xlsm gets opened and the field A2 shows up in debug.
Once I go to the workbook where I defined this module in and type =TestFunction() into a cell, I get a #VALUE!. The file also doesn't get opened.
If I comment these two lines:
Set ws = wk.Sheets(1)
Debug.Print ws.Range("A2")
the cell will show Success!, but the file still doesn't open.
What am I doing wrong? Both workbooks are .xlsm files. I am using Microsoft Office Excel 2007.
Just throw everything from mySub into the test function and if everything is successful have test function return the value of the cell. So testFunc = ws.Range("A2").
As DaveU already stated UDFs can only return values. I found a different workaround simply calling the function from within the VBA environment which lets me modify cell contents wherever I'd like.

Copying a Chart in VBA after Opening Excel File

I have a VBA Module in Word2007 with a main sub which calls an OpenExcelFile sub to open an Excel Workbook. It opens successfully, but then in my main sub, I am having trouble selecting and copying a particular chart. I want to then paste the chart into word as a picture.
Const Fuelpath As String = "\\PATH\Fuel_Price_Screen.xls"
Sub Main()
OpenExcelFile (Fuelpath)
'''This is where I would like to Copy the only Chart on the first Excel Sheet (named "$$Screen,"
'''but I keep getting errors. I would like to paste it into the Word doc called
'''"daily summary automation," which the VBA module is running in.
End Sub
Sub OpenExcelFile(ByVal Filepath As String)
Dim xlApp As Object
xlApp.Application.Visible = True
xlApp.Workbooks.Open (Fuelpath)
End Sub