2012-04-15 10 views
7

में के और एम खोजें VBA या kx+m string में "के" और "एम" चर खोजने के लिए एक सूत्र है?एक्सेल: "केएक्स + एम" टेक्स्ट स्ट्रिंग

कैसे KX + m स्ट्रिंग देख सकते हैं के लिए कई परिदृश्य, उदा .:

312*x+12 
12+x*2 
-4-x 

और इतने पर कर रहे हैं। मुझे पूरा यकीन है कि मैं Excel में बहुत जटिल सूत्रों को लिखकर इसे हल कर सकता हूं, लेकिन मुझे लगता है कि शायद किसी ने पहले ही इस तरह की समस्याओं को हल कर लिया है। यहाँ मेरी सबसे अच्छा शॉट अब तक है, लेकिन यह सभी स्थितियों अभी तक (जैसे जब वहाँ KX + m स्ट्रिंग में दो minuses हैं संभाल नहीं करता है:

=TRIM(IF(NOT(ISERROR(SEARCH("~+";F5))); IF(SEARCH("~+";F5)>SEARCH("~*";F5);RIGHT(F5;LEN(F5)-SEARCH("~+";F5));LEFT(F5;SEARCH("~+";F5)-1)); IF(NOT(ISERROR(SEARCH("~-";F5))); IF(SEARCH("~-";F5)>SEARCH("~*";F5);RIGHT(F5;LEN(F5)-SEARCH("~-";F5)+1);LEFT(F5;SEARCH("~*";F5)-1));"")))

+2

+ के रूप में StrFunc बदलें! एक दिलचस्प सवाल के लिए :) –

उत्तर

4

मुझे यकीन है कि यह आपकी मदद करेगा :)

इस फ़ंक्शन को मॉड्यूल में रखें:

Function FindKXPlusM(ByVal str As String) As String 
    Dim K As String, M As String 
    Dim regex As Object, matches As Object, sm As Object 

    '' remove unwanted spaces from input string (if any) 
    str = Replace(str, " ", "") 

    '' create an instance of RegEx object. 
    '' I'm using late binding here, but you can use early binding too. 
    Set regex = CreateObject("VBScript.RegExp") 
    regex.IgnoreCase = True 
    regex.Global = True 

    '' test for kx+m or xk+m types 
    regex.Pattern = "^(-?\d*)\*?x([\+-]?\d+)?$|^x\*(-?\d+)([\+-]?\d+)?$" 
    Set matches = regex.Execute(str) 
    If matches.Count >= 1 Then 
     Set sm = matches(0).SubMatches 
     K = sm(0) 
     M = sm(1) 
     If K = "" Then K = sm(2) 
     If M = "" Then M = sm(3) 
     If K = "-" Or K = "+" Or K = "" Then K = K & "1" 
     If M = "" Then M = "0" 
    Else 
     '' test for m+kx or m+xk types 
     regex.Pattern = "^(-?\d+)[\+-]x\*([\+-]?\d+)$|^(-?\d+)([\+-]\d*)\*?x$" 
     Set matches = regex.Execute(str) 
     If matches.Count >= 1 Then 
      Set sm = matches(0).SubMatches 
      M = sm(0) 
      K = sm(1) 
      If M = "" Then M = sm(2) 
      If K = "" Then K = sm(3) 
      If K = "-" Or K = "+" Or K = "" Then K = K & "1" 
      If M = "" Then M = "0" 
     End If 
    End If 
    K = Replace(K, "+", "") 
    M = Replace(M, "+", "") 

    '' the values found are in K & M. 
    '' I output here in this format only for showing sample. 
    FindKXPlusM = " K = " & K & "   M = " & M 
End Function 

फिर आप इसे मैक्रो उदा। इस तरह:

Sub Test() 
    Debug.Print FindKXPlusM("x*312+12") 
End Sub 

या इसे फ़ॉर्मूला की तरह उपयोग करें। उदा। एक सेल में इस डालकर:

=FindKXPlusM(B1) 

मैं दूसरा तरीका पसंद है (कम काम: पी)

मैं विभिन्न मूल्यों के साथ यह परीक्षण किया है और यहाँ मैं क्या मिल का एक स्क्रीनशॉट है:

Screenshot of Find KX+M Formula

आशा इस मदद करता है :)

+2

+1 अच्छा है। मुझे लगता है कि अगर आप रिवर्स में हैं तो मैं इसे संभालने का तरीका पसंद करता हूं :) –

+1

रीगेक्सपी स्ट्रिंग को पार्स करने का सबसे अच्छा तरीका है, लेकिन पार्सिंग इस एप्लिकेशन के लिए उपयोगी है। – brettdj

3

मैं के लिए खोज करने के लिए रेगुलर एक्सप्रेशन का उपयोग करेंगे एक या अधिक अंक; एम के लिए "* x" के बाद और के लिए "+" के बाद।

आपका उदाहरण पूर्णांक मान दिखाता है। क्या होगा यदि ढलान और अवरोध फ़्लोटिंग पॉइंट नंबर हैं? हस्ताक्षर किए गए मान? यह आपके उदाहरण से अधिक जटिल है सुझाव देंगे।

मैं सुझाव दूंगा कि सबसे सामान्य समाधान एक साधारण gra के साथ एक लेक्सर/पार्सर लिखना होगा आपके लिए इसे संभालने के लिए mmar। मुझे नहीं पता कि आपके लिए वीबी या .NET प्रस्ताव क्या है। एएनटीएलआर जावा-भूमि में एक समाधान होगा; एक एएनटीएलआर.NET है।

मुझे यकीन नहीं है कि यह सब प्रयास आपको क्या खरीदता है। निकाली गई सामग्री के साथ आप क्या करेंगे? मुझे लगता है कि उपयोगकर्ताओं के लिए संख्यात्मक प्रकार की कोशिकाओं को के और एम के लिए भरना उतना आसान होगा जितना कि स्ट्रिंग डालने और उन्हें निकालने के बजाय y = m*x + k की गणना करें।

How to turn a string formula into a "real" formula

+0

+1 मैं आपके साथ सहमत हूं :) यह ऐसा लगता है उससे अधिक जटिल है। अगर मैं गलत नहीं हूं तो एक 'केएक्स + एम' में अधिकतम 7 ऑपरेटर और 1 ऑपरेटर का न्यूनतम हो सकता है। और इस तरह के परिदृश्य में "के" और "एम" मान प्राप्त करने के लिए यह वास्तव में जटिल हो जाता है। –

4

यह तुलना में यह लगता है अधिक जटिल है:

अपने लक्ष्य को एक स्ट्रिंग का मूल्यांकन करने के लिए बस है, तो हो सकता है eval() अपने जवाब है। अगर मैं गलत नहीं हूं तो एक केएक्स + मीटर में अधिकतम 7 ऑपरेटर और 1 ऑपरेटर का न्यूनतम हो सकता है। और इस तरह के परिदृश्य में "के" और "एम" मान प्राप्त करने के लिए यह वास्तव में जटिल हो जाता है। - सिद्धार्थ राउत 33 मिनट पहले

duffymo की पोस्ट में मेरी टिप्पणी पर

बिल्डिंग

इस स्नैपशॉट विभिन्न संयोजनों से पता चलता "KX + m" हो सकता है

enter image description here

और जैसा कि पहले सुझाव दिया गया था, आप जो चाहते हैं उसे हासिल करना बहुत जटिल है। इस समय मेरे कमजोर प्रयास को "K" निकालने के लिए यहां दिया गया है। यह कोड किसी भी तरह से वर्गीकृत नहीं है :(इसके अलावा मैंने विभिन्न परिदृश्यों के साथ कोड का परीक्षण नहीं किया है, इसलिए यह दूसरों के साथ असफल हो सकता है। हालांकि यह आपको इस समस्या से संपर्क करने के बारे में एक उचित विचार देता है। आपको सटीक परिणाम प्राप्त करने के लिए इसे और अधिक ट्वीक करें।

कोड (मैं इस कोड में 7 संभावित संयोजनों के लिए परीक्षण कर रहा हूं।यह इन 7 के लिए काम करता है लेकिन/दूसरों के लिए असफल हो जायेगी हो सकता है)

Option Explicit 

Sub Sample() 
    Dim StrCheck As String 
    Dim posStar As Long, posBrk As Long, pos As Long, i As Long 
    Dim strK As String, strM As String 
    Dim MyArray(6) As String 

    MyArray(0) = "-k*(-x)+(-m)*(-2)" 
    MyArray(1) = "-k*x+(-m)*(-2)" 
    MyArray(2) = "-k(x)+(-m)*(-2)" 
    MyArray(3) = "-k(x)+(-m)(-2)" 
    MyArray(4) = "-kx+m" 
    MyArray(5) = "kx+m" 
    MyArray(6) = "k(x)+m" 

    For i = 0 To 6 
     StrCheck = MyArray(i) 
     Select Case Left(Trim(StrCheck), 1) 

     Case "+", "-" 
      posBrk = InStr(2, StrCheck, "(") 
      posStar = InStr(2, StrCheck, "*") 

      If posBrk > posStar Then   '<~~ "-k*(-x)+(-m)*(-2)" 
       pos = InStr(2, StrCheck, "*") 
       If pos <> 0 Then 
        strK = Mid(StrCheck, 1, pos - 1) 
       Else 
        strK = Mid(StrCheck, 1, posBrk - 1) 
       End If 
      ElseIf posBrk < posStar Then  '<~~ "-k(-x)+(-m)*(-2)" 
       pos = InStr(2, StrCheck, "(") 
       strK = Mid(StrCheck, 1, pos - 1) 
      Else        '<~~ "-kx+m" 
       '~~> In such a case I am assuming that you will never use 
       '~~> a >=2 letter variable 
       strK = Mid(StrCheck, 1, 2) 
      End If 
     Case Else 
      posBrk = InStr(1, StrCheck, "(") 
      posStar = InStr(1, StrCheck, "*") 

      If posBrk > posStar Then   '<~~ "k*(-x)+(-m)*(-2)" 
       pos = InStr(1, StrCheck, "*") 
       If pos <> 0 Then 
        strK = Mid(StrCheck, 1, pos - 2) 
       Else 
        strK = Mid(StrCheck, 1, posBrk - 1) 
       End If 
      ElseIf posBrk < posStar Then  '<~~ "k(-x)+(-m)*(-2)" 
       pos = InStr(1, StrCheck, "(") 
       strK = Mid(StrCheck, 1, pos - 2) 
      Else        '<~~ "kx+m" 
       '~~> In such a case I am assuming that you will never use 
       '~~> a >=2 letter variable 
       strK = Mid(StrCheck, 1, 1) 
      End If 
     End Select 

     Debug.Print "Found " & strK & " in " & MyArray(i) 
    Next i 
End Sub 

स्नैपशॉट

enter image description here

यह काफी नहीं है, लेकिन मैं यह सही रास्ते में आप हो जाता है आशा है कि ...

+0

+1 अच्छी तरह से – brettdj

+0

+1 माना जाता है बिना Regexp –

5

बजाय पार्स से परेशान एक सरल LINEST VBA में चलाते हैं।

जरूरत

Sub Extract() 
Dim strFunc As String 
Dim X(1 To 2) As Variant 
Dim Y(1 To 2) As Variant 
Dim C As Variant 

X(1) = 0 
X(2) = 100 

strFunc = "312*x+12" 
'strFunc = "12+x*2 " 
'strFunc = "-4-X" 

Y(1) = Evaluate(Replace(LCase$(strFunc), "x", X(1))) 
Y(2) = Evaluate(Replace(LCase$(strFunc), "x", X(2))) 
C = Application.WorksheetFunction.LinEst(Y, X) 

MsgBox "K is " & C(1) & vbNewLine & "M is " & C(2) 

End Sub 
+1

+1 बहुत रचनात्मक! – Excellll

संबंधित मुद्दे